HttpModule的作用
HttpModule的作用HttpModule是向实现类提供模块初始化和处置事件。当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。
一、asp.net的HTTP请求处理过程
(1)、客户端浏览器向服务器发出一个http请求,此请求会被inetinfo.exe进程截获,然后转交给aspnet_isapi.dll进程,接着它又通过Http Pipeline的管道,传送给aspnet_wp.exe这个进程,接下来就到了.net framework的HttpRunTime处理中心,处理完毕后就发送给用户浏览器。
(2)、当一个http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入到如下几个容器中:HttpModule --> HttpHandler Factory --> HttpHandler。当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了,客户端也就得到相应的东东了。
(3)完整的http请求在asp.net framework中的处理流程:
HttpRequest --> inetinfo.exe --> ASPNET_ISAPI.DLL --> Http Pipeline --> ASPNET_WP.EXE- -> HttpRuntime --> HttpApplication Factory --> HttpApplication --> HttpModule --> HttpHandler Factory --> HttpHandler --> HttpHandler.ProcessRequest()
也就是说一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。
而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。
(4)如果想在中途截获一个httpRequest并做些自己的处理,就应该在HttpRuntime运行时内部来做到这一点,确切的说是在HttpModule这个容器中来实现。
例如http requst 处理过程
二、常用的内部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都继承System.Web.IHttpModule接口,并实现接口的Init(HttpApplication context)和Dispose()方法。如下:
public class MyModule:IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.Write("BeginRequest");
}
public void Dispose()
{
}
}
Init():这个方法接受一个HttpApplication对象,HttpApplication代表了当前的应用程序,我们需要在这个方法内订阅 HttpApplication对象暴露给客户端的事件。可见,这个方法仅仅是用来对事件进行订阅,而实际的事件处理程序,需要我们另外写方法。
Dispose():在垃圾回收前释放资源。
整个过程很好理解:
1、当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。
2、在创建Module实例的时候会调用Module的Init()方法。
3、在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。
4、HttpApplication在其应用程序周期中触发各类事件。
5、触发事件的时候调用Module在其Init()方法中注册过的方法。
配置HttpModule
自定义HttpModule跟自定义HttpHandler相似,都要在web.config文件中进行配置。形式如下:
<HttpModules>
<add name="MM" type="MyModule,MMAssembly"/>
</HttpModules>
1.type:跟HttpHandler中的一样,有两部分组成,第一部分是完整的类名(含命名空间名),第二部分是所在程序集名(不含.dll)。
2.name:HttpModule的名称,可以跟类名无关。通过HttpApplication对象的Modules属性获取HttpModuleCollection,然后通过name获取对应的HttpModule对象;在Global.asax中通过方法名ModuleName_EventName订阅HttpModule中的事件,这里为MM_具体的事件名,详细请见下面实例。
3.因为对于每个进入工作进程的请求都会经过各已配置的HttpModule的处理(因为HttpModule是订阅应用程序级事件的),所以配置文件中没有path和verb属性(不管是*.aspx还是*.ashx,请求方式为get还是post都会进行处理)。
注意:HttpModule的配置是无需像HttpHandler那样在IIS上进行配置的。
四、实例:利用HttpModule实现终止此次HttpRequest请求
可以利用HttpModule通过调用HttpApplication.CompleteRequest()方法实现当满足某一个条件时终止此次的HTTP请求。
需要注意的是,即使调用了HttpApplication.CompleteRequest()方法终止了一个HTTP请求,ASP.NET Framework仍然会触发HttpApplication后面的这3个事件:EndRequest事件、PreSendRequestHeaders事件、PreSendRequestContent事件。
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace MyHttpModule
{
public class CompleteRequestHttpModule : IHttpModule
{
IHttpModule 成员
}
}