转自http://www.tracefact.net/Asp-Net/Introduction-to-Http-Module.aspx
HTTP Module概述
一般来说,我们可以将Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。而 Http Module 的作用是与应用程序事件 密切相关的。
我们通过Http Module在Http请求管道(Pipeline)中注册期望对应用程序事件做出反应的方法,在相应的事件触发的时候(比如说BeginRequest事件,它在应用程序收到一个Http请求并即将对其进行处理时触发),便会调用Http Module注册了的方法,实际的工作在这些方法中执行。.Net 本身已经有很多的Http Module,其中包括 表单验证Module(FormsAuthenticationModule), Session 状态Module(SessionStateModule),输出缓存Module (OutputCacheModule)等。
HttpModule是针对http请求的,所以每一个请求都会执行响应。而HttpHandler是针对某类文件或资源的,只有特殊的http请求才执行。
IHttpModule接口
asp.net中的HttpModule类是实现了接口IHttpModule的类。该接口仅包含两个方法
public void Init(HttpApplication context);
public void Dispose();
Init():这个方法接受一个HttpApplication对象,HttpApplication代表了当前的应用程序,我们需要在这个方法内注册 HttpApplication对象暴露给客户端的事件。可见,这个方法仅仅是用来对事件进行注册,而实际的事件处理程序,需要我们另外写方法。
整个过程很好理解:
- 当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。
- 在创建Module实例的时候会调用Module的Init()方法。
- 在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。
- HttpApplication在其应用程序周期中触发各类事件。
- 触发事件的时候调用Module在其Init()方法中注册过的方法
Dispose():它可以在进行垃圾回收之前进行一些清理工作。
HttpModule注册
asp.net中包含很多内置的HttpModule类,可打开C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/CONFIG/web.config文件,查看<httpmodules>节点值,可以看到系统内置的所有modules:
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
... 略
</httpModules>
注册自己订制的HttpModule时,只需在应用程序的web.config的<httpmodules/>节点中添加节点即可
<system.web>
<httpModules>
<add name="CustomModuleName" type="myNameSpace.ModuleDemo, myDll"/>
</httpModules>
</system.web>
其中,name属性为module的唯一标识,type属性由“,”隔开,左边为实现HttpModule的类全名,右边为所在程序集名称
内置HttpModule类
名称 | 类型 | 功能 |
OutputCache | System.Web.Caching.OutputCacheModule | 页面级输出缓存 |
Session | System.Web.SessionState.SessionStateModule | Session状态管理 |
WindowsAuthentication | System.Web.Security.WindowsAuthenticationModule | 用集成Windows身份验证进行客户端验证 |
FormsAuthentication | System.Web.Security.FormsAuthenticationModule | 用基于Cookie的窗体身份验证进行客户端身份验证 |
PassportAuthentication | System.Web.Security.PassportAuthenticationModule | 用MS护照进行客户身份验证 |
RoleManager | System.Web.Security.RoleManagerModule | 管理当前用户角色 |
UrlAuthorization | System.Web.Security.UrlAuthorizationModule | 判断用户是否被授权访问某一URL |
FileAuthorization | System.Web.Security.FileAuthorizationModule | 判断用户是否被授权访问某一资源 |
AnonymousIdentification | System.Web.Security.AnonymousIdentificationModule | 管理Asp.Net应用程序中的匿名访问 |
Profile | System.Web.Profile.ProfileModule | 管理用户档案文件的创立 及相关事件 |
ErrorHandlerModule | System.Web.Mobile.ErrorHandlerModule | 捕捉异常,格式化错误提示字符,传递给客户端程序 |
定制HttpModule
要订制自己的HttpModule,只需实现IHttpModule接口,然后在配置文件中这册既可。
如前所述,在Init()方法中注册希望响应的事件,并完成事件处理程序。在应用程序生命周期中,发生该事件时,就会调用注册的事件处理程序。
此示例为向输出流中添加信息。
可注册的事件
HttpApplication类中封装了处理请求的过程中可触发的不同事件。
事件名 | 说 明 |
AcquireRequestState | 在ASP.NET运行时准备获得当前HTTP请求的会话状态时触发 |
AuthenticateRequest | 在ASP.NET运行时准备验证用户的身份时触发 |
AuthorizeRequest | 在ASP.NET运行时准备给用户授予资源时触发 |
BeginRequest | 在ASP.NET运行时收到一个新HTTP请求时触发 |
Disposed | 在ASP.NET处理完HTTP请求时触发 |
EndRequest | 在把响应内容发送给客户机之前触发 |
Error | 在处理HTTP请求的过程中发生未处理的异常时触发 |
PostRequestHandlerExecute | 在HTTP处理程序执行完后触发 |
PreRequestHandlerExecute | 在ASP.NET开始执行HTTP请求的处理程序之前触发。在这个事件后,ASP.NET会把请求发送给合适的HTTP处理程序 |
PreSendRequestContent | 在ASP.NET把相应内容发送给客户机之前触发。这个事件可以修改相应内容,之后把它发送给客户机。可以使用这个事件给页面输出添加所有页面中都有的公共内容 |
PreSendRequestHeaders | 在ASP.NET把HTTP响应标题发送给客户机之前触发。这个事件可以修改标题,之后把它发送给客户机。可以使用这个事件给标题添加Cookie和定制数据 |
。。。。。。。。。。 | 。。。。。。。。。。。。。。 |
可注册的事件涉及到应用程序生命周期的每个事件,客户程序可以在其中加入自己的操作以控制响应。
Global.asax文件与 Http Module
Global.asax文件主要用于放置对于应用程序(Application)事件或者会话(Session)事件的响应程序。熟悉的有Application_Start、Application_End、Session_Start、Session_End 等。
在asp.net中,Glabal不仅可以注册应用程序和Session事件,还可以注册Http Module暴露出的事件;不仅可以注册系统Module的事件,也可以注册我们自己义的Module暴露出的事件。在具体介绍之前,这里需要首先注意两点:
- 在每处理一个Http请求时,应用程序事件都会触发一遍,但是Application_Start和 Application_End 例外,它仅在第一个资源文件被访问时被触发。
- Http Module无法注册和响应Session事件,对于Session_Start 和 Session_End,只能通过Glabal.asax来处理。
接下来,我们在站点中创建一个 Global.asax 文件,在里面添加如下代码,注意到格式是:void 模块名_事件名(object sender, EventArgs e)。
通过这种方式,可以将 Glabal.asax文件与我们自己定义的Http Module所暴露出的事件 ExposedEvent 联系到了一起