理解並自定義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事件。具體實現機制有待研究!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM