HttpModule是向實現類提供模塊初始化和處置事件。當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還并沒有對這個HTTP請求做任何處理,也就是說此時對于HTTP請求來講,HttpModule是一個HTTP請求的“必經之路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息作一些額外的工作,或者在某些情況下干脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。
(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這個容器中來實現。
負責監聽HttpRequest,同時對HttpRequest增添或者過濾掉一部分內容。也就是說,當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還并沒有對這個HTTP請求做任何處理,也就是說此時對于HTTP請求來講,HttpModule是一個HTTP請求的“必經之路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息作一些額外的工作,或者在某些情況下干脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。HttpModule實現了接口IHttpModule,我們可以自定義實現該接口的類,從而取代HttpModule。
要實現HttpModule,必須實現接口IHttpModule。下面是IHttpModule接口分析:

using System;namespace System.Web{ public interface IHttpModule { // 銷毀不再被HttpModule使用的資源 void Dispose(); // 初始化一個Module,為捕獲HttpRequest做準備 void Init(HttpApplication context); }}
下面是自己的HttpModule:
1.當站點第一個資源被訪問的時候,Asp.Net會創建HttpApplication類的實例,它代表著站點應用程序,同時會創建所有在Web.Config中注冊過的Module實例。 2.在創建Module實例的時候會調用Modul的Init()方法。 3.在Init()方法內,對想要作出響應的HttpApplication暴露出的事件進行注冊。(僅僅進行方法的簡單注冊,實際的方法需要另寫)。 4.HttpApplication在其應用程序周期中觸發各類事件。 5.觸發事件的時候調用Module在其Init()方法中注冊過的方法。

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace Learning{ public class ModuleDemo : IHttpModule { // Init方法僅用于給期望的事件注冊方法 public void Init(HttpApplication context) { context.EndRequest += new EventHandler(context_EndRequest); context.BeginRequest += new EventHandler(context_BeginRequest); } // 處理BeginRequest 事件的實際代碼 void context_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; context.Response.Write("<h1 style='color:#00f'>來自HttpModule 的處理,請求到達</h1><hr>"); } // 處理EndRequest 事件的實際代碼 void context_EndRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; context.Response.Write("<hr><h1 style='color:#f00'>來自HttpModule的處理,請求結束</h1>"); } public void Dispose() { } }}
web.config

<configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpModules> <add name="up" type="Learning.ModuleDemo,Learning"/> </httpModules> </system.web></configuration>

在這冊我們自己的http module 時,假設類名為ModuleDemo,位于Learning命名空間下,程序集名稱為Learning,我們只需將Learning拷貝到Bin目錄下,并在站點的 web.config 文件 system.web 結點下創建 httpModules 結點:
運行結果:

|
新聞熱點
疑難解答