理解并自定义HttpModule

前言                                  

  继上一篇理解并自定义HttpHandler后,有进行了HttpModule的进一步学习,本篇作为一个小结。

  主要参考:Asp.Net 构架(HttpModule 介绍) - Part.3

目录                                  

1.到底什么是HttpModule?

2.系统内部的HttpModule。

3.配置HttpModule。

4.自定义HttpModule。

5.Global.asax文件与HttpModule。

 

到底什么是HttpModule                          

  Asp.net的事件分为三级:应用程序级、页面级和控件级。而HttpModule是通过在管道模型中对Asp.net的应用程序级事件进行订阅,当应用程序级事件触发时调用HttpModule中对应的处理方法。也就是说HttpModule是订阅Asp.net应用程序级事件的入口,依附于HttpApplication对象生命周期的各个事件。

 

系统内部的HttpModule                          

  Asp.net内部很多功能都以HttpModule形式来实行,如Windows、Forms和PassPort认证、Session机制等。下面是部分的内部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跟自定义HttpHandler相似,都要在web.config文件中进行配置。形式如下:

1 <HttpModules>
2 <add name="MM" type="MyModule,MMAssembly"/>
3 </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                             

  每个HttpModule都继承System.Web.IHttpModule接口,并实现接口的Init(HttpApplication context)和Dispose()方法。如下:

 1 public class MyModule:IHttpModule
2 {
3
4 public void Init(HttpApplication context)
5 {
6 context.BeginRequest += new EventHandler(context_BeginRequest);
7 }
8
9 void context_BeginRequest(object sender, EventArgs e)
10 {
11 HttpContext.Current.Response.Write("BeginRequest");
12 }
13
14 public void Dispose()
15 {
16 }
17 }

Init():这个方法接受一个HttpApplication对象,HttpApplication代表了当前的应用程序,我们需要在这个方法内订阅 HttpApplication对象暴露给客户端的事件。可见,这个方法仅仅是用来对事件进行订阅,而实际的事件处理程序,需要我们另外写方法。

Dispose():在垃圾回收前释放资源。

整个过程很好理解:

  1. 当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。
  2. 在创建Module实例的时候会调用Module的Init()方法。
  3. 在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。
  4. HttpApplication在其应用程序周期中触发各类事件。
  5. 触发事件的时候调用Module在其Init()方法中注册过的方法。

关于委托可参考:委托与事件

 

Global.asax文件与 HttpModule                    

在asp.net中,Glabal不仅可以注册应用程序和Session事件,还可以注册Http Module暴露出的事件;不仅可以注册系统Module的事件,也可以注册我们自己义的Module暴露出的事件。在具体介绍之前,这里需要首先注意两点:

  1. 在每处理一个Http请求时,应用程序事件都会触发一遍,但是Application_Start和 Application_End 例外,它仅在第一个资源文件被访问时被触发。
  2. Http Module无法注册和响应Session事件,对于Session_Start 和 Session_End,只能通过Glabal.asax来处理。

继续上面的例子:

MyModule.cs文件

 1 public class MyModule:IHttpModule
2 {
3 public event EventHandler ExposedEvent;//HttpModule事件,供Global.asax来订阅
4
5 public void Init(HttpApplication context)
6 {
7 context.BeginRequest += new EventHandler(context_BeginRequest);//订阅HttpApplication的事件
8 }
9
10 void context_BeginRequest(object sender, EventArgs e)
11 {
12 HttpContext.Current.Response.Write("BeginRequest");
13 OnExposedEvent(new EventArgs());//触发HttpModule自定义事件
14 }
15
16 protected void OnExposedEvent(EventArgs e)
17 {
18 if (ExposedEvent != null)
19 {
20 ExposedEvent(this, e);
21 }
22 }
23
24 public void Dispose()
25 {
26 }
27 }

Global.asax文件

1 void MyModule_ExposedEvent(object sender, EventArgs e)
2 {
3 Response.Write("xixi");
4 }

上面的MyModule_ExposedEvent方法就会自动订阅了MyModule中的ExposedEvent事件。具体实现机制有待研究!

posted @ 2012-02-06 10:35  ^_^肥仔John  阅读(5020)  评论(3编辑  收藏  举报