写在前面

关于IHttpModule的相关内容,在面试的时候也被问到过,当时也是隐隐约约的感觉这个接口有一个Init方法,可以在实现类中的Init方法注册一系列的事件,说句实话,具体哪些事件,忘了差不多了。今天周末在家,也确实没什么事,就算是对这块知识进行查漏补缺了。

IHttpModule工作方式

熟悉asp.net生命周期的朋友,应该知道HttpModule的执行是在HttpHandler之前被执行,执行HttpModule的一系列事件后然后执行HttpHandler,然后又执行HttpModule的一些事件。具体的可以参考下面的生命周期的图。

而HttpHandler才是处理http请求的地方,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。

一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。

而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。

一个实例

项目结构

MyHttpModule代码

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MyHttpModule
{
/// <summary>
/// 自定义HttpModule
/// </summary>
public class MyHttpModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
} void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的EndRequest"); }
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的BeginRequest"); }
}
}
}

在web.config注册自定义的HttpModule

 <?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" /> </system.web>
<system.webServer>
<modules>
<add name="MyHttpModule" type="MyHttpModule.MyHttpModule,MyHttpModule"/>
</modules>
</system.webServer>
</configuration>

浏览页面Default.aspx

那么在生命周期过程中的一系列的事件的执行顺序是怎样的呢?

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MyHttpModule
{
/// <summary>
/// 自定义HttpModule
/// </summary>
public class MyHttpModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
context.PostAcquireRequestState += context_PostAcquireRequestState;
context.PostAuthenticateRequest += context_PostAuthenticateRequest;
context.PostAuthorizeRequest += context_PostAuthorizeRequest;
context.PostLogRequest += context_PostLogRequest;
context.PostMapRequestHandler += context_PostMapRequestHandler;
context.PostRequestHandlerExecute += context_PostRequestHandlerExecute;
context.PostResolveRequestCache += context_PostResolveRequestCache;
context.PostUpdateRequestCache += context_PostUpdateRequestCache;
context.PreRequestHandlerExecute += context_PreRequestHandlerExecute;
context.PreSendRequestContent += context_PreSendRequestContent;
context.PreSendRequestHeaders += context_PreSendRequestHeaders;
context.RequestCompleted += context_RequestCompleted;
context.ResolveRequestCache += context_ResolveRequestCache;
context.UpdateRequestCache += context_UpdateRequestCache;
context.ReleaseRequestState += context_ReleaseRequestState;
} void context_UpdateRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的UpdateRequestCache<br/>");
}
} void context_ResolveRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的ResolveRequestCache<br/>");
}
} void context_RequestCompleted(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的RequestCompleted<br/>");
}
} void context_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreSendRequestHeaders<br/>");
}
} void context_PreSendRequestContent(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreSendRequestContent<br/>");
}
} void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreRequestHandlerExecute<br/>");
}
} void context_PostUpdateRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostUpdateRequestCache<br/>");
}
} void context_PostResolveRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostResolveRequestCache<br/>");
}
} void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostRequestHandlerExecut<br/>");
}
} void context_PostMapRequestHandler(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostMapRequestHandler<br/>");
}
} void context_PostLogRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostLogRequest<br/>");
}
} void context_PostAuthorizeRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAuthorizeRequest<br/>");
}
} void context_PostAuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAuthenticateRequest<br/>");
}
} void context_PostAcquireRequestState(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAcquireRequestState<br/>");
}
} void context_ReleaseRequestState(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的ReleaseRequestState<br/>");
}
} void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的EndRequest<br/>");
}
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的BeginRequest<br/>"); }
}
}
}

浏览结果

使用HttpModule终止此次Http请求

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace MyHttpModule
{
public class EndModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender; application.CompleteRequest(); application.Context.Response.Write("请求被终止。"); }
}
}

结果

总结

这里介绍了在asp.net生命周期中一个最重要的接口IHttpModule,可以这样来形容该接口,事件接口,因为在实现类中的Init方法中,可以注册生命周期中的各种事件,并可以在事件中定义各种逻辑。

参考文章

一点一点学ASP.NET之基础概念——HttpModule 文野

IHttpModule的那些事的更多相关文章

  1. IHttpModule理解-知识补充

    文章:IHttpModule的那些事 可以自定义类实现IHttpModule接口,然后实现接口方法Init,Init方法可以得到HttpApplication 的实例化对象. 然后给对象的事件的注册各 ...

  2. IHttpHandler的那些事

    写在前面 从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结.发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口.当然,一般处 ...

  3. 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架

    题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...

  4. MVC4多语言IHttpModule实现

    最近项目需要多语言环境了. 由于项目页面较多,逐个Action去读取资源文件不大现实.就想到了使用 IHttpModule配合MVC的路由规则来实现. 首先创建以个mvc4的应用程序,添加资源文件夹( ...

  5. IHttpModule与IHttpHandler的区别整理

    IHttpModule与IHttpHandler的区别整理1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行 ...

  6. HTTP请求处理流程、IHttphandler、IHttpModule

    一.ASP.NET处理管道 Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息. HttpWorkerRequest把请求传递给HttpRunt ...

  7. 【腾讯Bugly干货分享】H5 视频直播那些事

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...

  8. CSharpGL(31)[译]OpenGL渲染管道那些事

    CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...

  9. TODO:字节的那点事Go篇

    TODO:字节的那点事Go篇 (本文go version go1.7.3 darwin/amd64) 在Golang中string底层是由byte数组组成的. fmt.Println(len(&quo ...

随机推荐

  1. vue-cli3 创建选项选择

    1.创建新项目: vue create hello-world 2.选择配置 3.自定义选择配置,需要什么就选什么 4. 是否使用带历史纪录的路由,这里一般是Y 5.预编译器选择什么 6.eslint ...

  2. 大专生自学php到找到工作的前前后后

    先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...

  3. Hbase(2)-HBase简介

    一. HBase的特点 1. 海量存储 Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据.这与Hbase的极易扩展性息息相关.正式因为Hb ...

  4. Selenium_python自动化环境搭建篇

    説 明: 本篇随笔讲解Selenium+python自动化环境的搭建,此随笔暂不介绍Selenium3,Selenium3需要考虑环境依赖驱动等相关问提比较多一篇随笔没法説完,所以暂不介绍,当然你可以 ...

  5. scala 时间格式转换(String、Long、Date)

    1)scala 时间格式转换(String.Long.Date) 1.时间字符类型转Date类型 [java] view plain copy import java.text.SimpleDateF ...

  6. 第十四周 P187教材检查

    在IDEA中或命令行中运行P187 Guess.java. 这道题是继承语法抽象类一块的知识点,题目本身其实并不难,但是当时做的时候我找自己原来的代码花了很长时间,刚找到运行完截好图,就到时间了. 当 ...

  7. 201555301 2016-2017-2《Java程序设计》课程总结

    20155301 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:我对师生关系的思考 预备作业2:从现有技能获取的经验应用于JAVA中 预备作业 ...

  8. EXCEL 处理重复数据名字后面追加值

    近期要用 EXCEL 处理重复数据名字后面追加值的,如图: 先排序,再根据条件追加 [公式]=+B6&IF(COUNTIF($B$6:B6,B6)-1>0,"_" & ...

  9. Deep Learning 教程翻译

    Deep Learning 教程翻译 非常激动地宣告,Stanford 教授 Andrew Ng 的 Deep Learning 教程,于今日,2013年4月8日,全部翻译成中文.这是中国屌丝军团,从 ...

  10. Intellij IDEA 2017 通过scala工程运行wordcount

    首先是安装scala插件,可以通过idea内置的自动安装方式进行,也可以手动下载可用的插件包之后再通过idea导入. scala插件安装完成之后,新建scala项目,右侧使用默认的sbt 点击Next ...