ASP.NET Framework 處理一個 Http Request 的流程:html
HttpRequest → inetinfo.exe → ASPNET_ISAPI.dll → ASPNET_WP.exe → HttpRuntime → HttpApplication Factory → HttpApplication → HttpModule → HttpHandler Factory → HttpHandler → HttpHandler.ProcessRequest()web
ASP.NET 請求處理過程是基於管道模型的,ASP.NET 把 http 請求依次傳遞給管道中各個 HttpModule,最終被 HttpHandler 處理,處理完成後,再次通過管道中的 HttpModule,把結果返回給客戶端。注意:在 http 請求的處理過程當中,只能調用一個 HttpHandler,但能夠調用多個 HttpModule。api
在每一個 HttpModule 中均可以干預請求的處理過程。當請求到達 HttpModule 的時候,系統尚未對這個請求真正處理,可是咱們能夠在這個請求傳遞處處理中心(HttpHandler)以前附加一些其它信息,截獲這個請求並做一些額外的工做,或者終止請求等。在 HttpHandler 處理完請求以後,咱們也能夠再在相應的 HttpModule 中把請求處理的結果進行再次加工後返回客戶端。緩存
HttpModule 是實現了 System.Web.IhttpModule 接口的類。IHttpModule 接口的聲明:服務器
public interface IHttpModule
{
// 給予 HTTP 模塊在對象被垃圾收集以前執行清理的機會,通常無需編寫代碼。
void Dispose();
// 初始化時自動調用,可在這裏向 HttpApplication 對象中的事件註冊本身的事件處理程序
void Init(HttpApplication context);
}
HttpModule 能夠向 System.Web.HttpApplication 對象註冊下面一系列事件(事件觸發順序已排序):cookie
其他,還有 Error 事件(在處理 HTTP 請求的過程當中出現未處理的異常時觸發),Deposed 事件(當 ASP.NET 完成 HTTP 請求的處理過程時觸發),UpdateRequestCache 事件(當 ASP.NET 完成了當前的 HTTP 請求的處理,而且輸出內容已經準備好添加給輸出緩存時觸發。這依賴於 Web 應用程序的輸出緩存是如何設置的)。app
HttpModule & HttpHandler 的生命週期圖:框架
有的網站每個頁面都會彈出一個廣告或在每一個頁面都以註釋形式(<!-- -->)加入網站的版權信息。若是在每一個頁面教編寫這樣的 JS 代碼,編寫會很繁瑣,更改和維護將很是困難。
HttpModule 是客戶端發出請求到客戶端接收到服務器響應之間的一段必經之路。咱們徹底能夠在服務器處理完請求以後,並在向客戶端發送響應文本以前這段時機,把這段註釋文字添加到頁面文本以後。這樣,每個頁面請求都會被附加上這段註釋文字。那麼,這段代碼究竟該在哪一個事件裏實現呢? PostRequestHandlerExecute 和 PreSendRequestContent 之間的任何一個事件均可以,但通常會在 EndRequest 事件裏編寫代碼,具體實現步驟以下: 網站
public class TestModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.EndRequest += context_EndRequest;
}
void context_EndRequest(object sender, EventArgs e)
{
((HttpApplication)sender).Response.Write("<!-- 公司版權 -->");
}
}
<httpModules>
<add name="TestModule" type="ASP.NET_Web_Form.Util.TestModule,ASP.NET_Web_Form.Util"/>
</httpModules>
在做登陸時,登陸成功後,通常要把用戶名放在 Session 中保存,在其它每個頁面的 Page_Load 事件中都檢查 Session 中是否存在用戶名,若是不存在就說明用戶未登陸,就不讓其訪問其中的內容。但這種作法實在是太笨拙,幾乎要在每個頁面中都加入檢測 Session 的代碼,致使難以開發和維護。下面咱們看看如何使用 HttpModule 來減小咱們的工做量。(若是每一個頁面都有共同的父類,例如 BasePage,那麼在父類的 Load 事件中檢測也是同樣的只需寫一次檢測代碼)
因爲這裏要用到 Session 中的內容,咱們只能在 AcquireRequestState 和 PreRequestHandlerExecute 事件中編寫代碼,由於在 HttpModule 中只有這兩事件中能夠訪問 Session。這裏能夠選擇PreRequestHandlerExecute 事件編寫代碼,具體實現比較簡單,就不貼代碼了。 ui
HttpHandler 是 HTTP 請求的處理中心,真正地對客戶端請求的服務器頁面作出編譯和執行,並將處理事後的信息附加在 HTTP 請求信息流中再次返回到 HttpModule 中。與 HttpModule 不一樣,一旦定義了本身的HttpHandler 類,那麼它對系統的 HttpHandler 的關係將是「覆蓋」。
在 web.config 中配置 HttpHandler 節時,你能夠指定 HTTP 的動詞(GET,POST),指定要處理的資源是什麼,以及用什麼 HttpHandler 來進行。
另外,若是要在 HttpHandler 中使用 Session,那必須把該 HttpHandler 實現 IRequiresSessionState 接口,IRequiresSessionState 接口是個空接口,它沒有抽象方法,只是一個標記接口。
本文參考文獻:http://www.cnblogs.com/yuanyuan/archive/2010/11/15/1877709.html