理解并自定义HttpModule

时间:2022-04-22
本文章向大家介绍理解并自定义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事件。具体实现机制有待研究!