HttpModule是向實現類提供模塊初始化和處置事件。當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還並無對這個HTTP請求作任何處理,也就是說此時對於HTTP請求來說,HttpModule是一個HTTP請求的「必經之路」,因此能夠在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)以前附加一些須要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息做一些額外的工做,或者在某些狀況下乾脆終止知足一些條件的HTTP請求,從而能夠起到一個Filter過濾器的做用。web
(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() api
也就是說一個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這個容器中來實現。app
負責監聽HttpRequest,同時對HttpRequest增添或者過濾掉一部份內容。也就是說,當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還並無對這個HTTP請求作任何處理,也就是說此時對於HTTP請求來說,HttpModule是一個HTTP請求的「必經之路」,因此能夠在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)以前附加一些須要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息做一些額外的工做,或者在某些狀況下乾脆終止知足一些條件的HTTP請求,從而能夠起到一個Filter過濾器的做用。
HttpModule實現了接口IHttpModule,咱們能夠自定義實現該接口的類,從而取代HttpModule。
asp.net
要實現HttpModule,必須實現接口IHttpModule。下面是IHttpModule接口分析:ui
using System; namespace System.Web { public interface IHttpModule { // 銷燬再也不被HttpModule使用的資源 void Dispose(); // 初始化一個Module,爲捕獲HttpRequest作準備 void Init(HttpApplication context); } }
下面是本身的HttpModule:spa
1. 當站點第一個資源被訪問的時候,Asp.Net會建立HttpApplication類的實例,它表明着站點應用程序,同時會建立全部在Web.Config中註冊過的Module實例。
2. 在建立Module實例的時候會調用Modul的Init()方法。
3. 在Init()方法內,對想要做出響應的HttpApplication暴露出的事件進行註冊。(僅僅進行方法的簡單註冊,實際的方法須要另寫)。
4. HttpApplication在其應用程序週期中觸發各種事件。
5. 觸發事件的時候調用Module在其Init()方法中註冊過的方法。.net
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.configdebug
<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 結點:
運行結果: