[轉]ASP.NET必須知道的:HttpModule,HttpHandler

一 asp.net請求的處理過程
-------------------
HttpModule 必須要掌握的東西
HttpHandler 必須要掌握的東西,非常有用
以上兩個的實例
---------------------
asp.net 事件模型機制

-----------------------

客戶的請求頁面由aspnet_isapi.dll這個動態連接庫來處理,把請求的aspx文件發送給CLR進行編譯執行,然後把Html流返回給瀏覽器
--------------------------
二 頁面事件
執行順序
Page_Init:初始化值或連接
Page_Load:主要使用IsPostBack,該事件主要執行一系列得操作來首次創建asp.net頁面或響應
由投遞引起得客戶端事件。在此事件之前,已還原頁面和控件視圖狀態。
Page_DataBind:在頁面級別上調用,也可在單個控件中調用。
DataBind_PreRender:數據綁定預呈現,恰好在保存視圖狀態和呈現控件之前激發此事件。
Page_Unload:此事件是執行最終清理工作的。
非確定事件
Page_Error:如果在頁面處理過程中出現未處理的例外,則激發error事件。
Page_AbortTransaction:交易事件,事務處理中如果已終止交易,則激發此事件,購物車常用。
Page_CommitTransaction:如果已成功交易,則激發此事件。
--------------------------------------------------------
Global.asax中的事件(執行順序)
Application_Start:應用程序啓動時激發
Application_BeginRquest:http請求開始時激發
Application_AuthenticateRequest: 應用程序批准http請求時激發
Session_Start: 會話啓動時激發
Application_EndRequest:Htttp請求結束時激發
Session_End:會話結束時激發
Application_End:應用程序結束時激發
Application_Error: 發生錯誤時激發
----------------------
ISAPI: 向web服務器插入某些組建,擴展功能,增強web服務器功能。
ISAPI: 擴展,win32的動態鏈接庫,譬如aspnet_isapi.dll,可以把ISAPI擴展看作是一個普通的應用程序,它處理的目標是HTTP請求。
ISAPI: 過濾器,web服務器把請求傳遞給相關的過濾器,接下來過濾器可能修改請求,執行某些操作等等。
ASP.NET請求的處理過程:
基於管道模型,在模型中ASP.NET把http請求傳遞給管道中所有的模塊。每個模塊都接收HTTP請求,並有完全的控制權。一旦請求經過了所有的HTTP模塊,最終被HTTP處理程序處理。HTTP處理程序對請求進行一些處理,並且結果將再次經過模塊管道中的HTTP模塊。
-----------
httpmodule
ISAPI過濾器(篩選器):IIS本身是不支持動態頁面的,也就是說他僅僅支持靜態HTML頁面的內容,對於.asp .aspx .cgi .php等,IIS並不知道如果處理這些後綴標記,它就會把它當作文本,絲毫不做處理髮送到客戶端。爲了解決這個問題,IIS有一種機制,叫做ISAPI的過濾器。它是一個COM組件。
ASP.NET服務在註冊到IIS的時候,會把每個擴展可以處理的文件擴展名註冊到IIS裏面(如*.ascx *.aspx等)。擴展啓動後,就根據定義好的方式來處理IIS所不能處理的文件,然後把控制權跳轉到專門處理代碼的進程中,asp.net中是aspnet_isapi.dll。讓這個進程開始處理代碼,生成標準的HTML代碼,生成後把這些代碼加入到原有的HTML中,最後把完整的HTML返回給IIS,IIS再把內容發送到客戶端。
----------------
HttpModule
Http模塊實現了過濾器(ISAPI filter)的功能,它是實現了System.Web.IHttpModule接口的.net組件。。這些組件通過在某些事件中註冊自身,把自己插入到ASP.NET請求處理管道。當這些事件發生的時候,ASP.NET調用對請求有興趣的HTTP模塊,這樣該模塊就能處理請求了。有時候需要過慮一下http請求,注意它不是覆蓋其他的包括系統自帶的HttpModule,在Machine.config中配置完成。
--------------------------------------
HttpHandler
它實現了ISAPI Extention的功能,它處理請求(Request)的信息和發送響應(Response)。HttpHandler功能的通過必須實現IHttpHandler接口。HTTP處理程序是實現System.Web.IHttpHandler接口的.NET組件。任何實現了該接口的類都可以用於處理輸入的Http請求。它就是Http處理程序。

在以前的ASP時候,當請求一個*.asp頁面文件的時候,這個HTTP請求首先會被一個名爲inetinfo.exe進程所截獲,這個進程實際上就是www服務。截獲之後它會將這個請求轉交給asp.dll進程,這個進程就會解釋這個asp頁面,然後將解釋後的數據流返回給客戶端瀏覽器。其實ASP.DLL是一個依附在IIS的ISAPI文件,它負責了對諸如ASP文件,ASA等文件的解釋執行,
-------------------------------------


ASP.NET的HTTP請求處理方法
當客戶端向web服務器請求一個*.aspx的頁面文件時,同asp類似,這個http請求也會被inetinfo.exe進程截獲(www服務),它判斷文件後綴之後,把這個請求轉交給ASPNET_ISAPI.DLL而ASPNET_ISAPI.DLL則會通過一個Http PipeLine的管道,將這個http請求發送給ASPNET_WP.EXE進程,當這個HTTP請求進入ASPNET_WP.EXE進程之後,asp.net framework就會通過HttpRuntime來處理這個Http請求,處理完畢後將結果返回給客戶端。
------------------------------------
當一個http請求被送入到HttpRuntime之後,這個Http請求會繼續被送入到一個被稱之爲HttpApplication Factory的一個容器當中,而這個容器會給出一個HttpApplication實例來處理傳遞進來的http請求,而後這個Http請求會依次進入到如下幾個容器中:
HttpModule --> HttpHandler Factory --> HttpHandler
當系統內部的HttpHandler的ProcessRequest方法處理完畢之後,整個Http Request就被處理完成了,客戶端也就得到相應的東東了。
完整的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()
如果想在中途截獲一個httpRequest並做些自己的處理,就應該在HttpRuntime運行時內部來做到這一點,確切的說時在HttpModule這個容器中做到這個的。
----------------------------------------
-------------------------------------
系統本身的HttpModule實現一個IHttpModule的接口,當然我們自己的類也能夠實現IHttpModule接口,這就可以替代系統的HttpModule對象了。
ASP.NET系統中默認的HttpModule:

DefaultAuthenticationModule 確保上下文中存在 Authentication 對象。無法繼承此類。
FileAuthorizationModule 驗證遠程用戶是否具有訪問所請求文件的 NT 權限。無法繼承此類。
FormsAuthenticationModule 啓用 ASP.NET 應用程序以使用 Forms 身份驗證。無法繼承此類。
PassportAuthenticationModule 提供環繞 PassportAuthentication 服務的包裝。無法繼承此類。
SessionStateModule    爲應用程序提供會話狀態服務。
UrlAuthorizationModule    提供基於 URL 的授權服務以允許或拒絕對指定資源的訪問。無法繼承此類。
WindowsAuthenticationModule 啓用 ASP.NET 應用程序以使用 Windows/IIS 身份驗證。無法繼承此類

--------------------------------------
這些系統默認的HttpModule是在文件machine.config中配置的,和我們開發時使用到的web.config的關係是:是在ASP.NET FRAMEWORK啓動處理一個Http Request的時候,它會依次加載machine.config和請求頁面所在目錄的web.config文件,如果在machine中配置了一個自己的HttpModule,你仍然可以在所在頁面的web.config文件中remove掉這個映射關係。
public class HelloWorldModule : IHttpModule
{
    public HelloWorldModule()
    {
    }

    public String ModuleName
    {
        get { return "HelloWorldModule"; }
    }

    // In the Init function, register for HttpApplication
    // events by adding your handlers.
    public void Init(HttpApplication application)
    {
        application.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest +=
            (new EventHandler(this.Application_EndRequest));
    }

    private void Application_BeginRequest(Object source,
         EventArgs e)
    {
    // Create HttpApplication and HttpContext objects to access
    // request and response properties.
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<h1><font color=red> HelloWorldModule: Beginning of Request</font></h1><hr>");
    }

    private void Application_EndRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>");
    }

    public void Dispose()
    {
    }
}

    <system.web>
   <httpModules>
    <add name="HelloWorldModule" type="HelloWorldModule"/>
   </httpModules>
    </system.web>
-----------------------------------------------------------------------------------
深入HttpModule
一個Http請求在被ASP.NET Framework捕獲之後會依次交給HttpModule以及HttpHandler來處理。hm與hh之間不是完全獨立的,實際上,http請求在hm傳遞的過程中會在某個事件內將控制權轉交給hh的,而真正的處理在HttpHandler中執行完成後,HttpHandler會再次將控制權交還給HttpModule
上面的代碼中的HttpModule的Init()中的參數是HttpApplication類型,它具有許多事件,包括BeginRequest,EndRequest,AuthentiacteRequest 等等。
-----------------------------------------------------------------
IHttpHandler
它是asp.net Framework提供的一個接口,定義瞭如果要實現一個Http請求的處理所需要必須實現的一些系統約定。也就是說,如果你想要自行處理某些類型的HTTP請求信息流的話,你需要實現這些系統約定才能做到。譬如一個*.aspx文件,用來處理此類型的Http請求,ASP.NET FRAMEWORK將會交給一個名爲System.Web.UI.PageHandlerFactory的HttpHandler類來處理。
HH和HM一樣,系統會在最初始由ASP.NET FRAMEWORK首先加載machine.config中的HttpHandler,而後會加載Web應用程序所在目錄的web.config中的用戶自定義的HttpHandler類。但是系統與我們自定義的HH之間的關係是"覆蓋"的,也就是說如果我們自定義了一個針對"*.aspx"的HttpHandler類的話,那麼系統會將對此http請求的處理權完全交給我們自己定義的這個HttpHandler類來處理,而我們自己的HttpHandler類則需要自己完全解析這個Http請求,並作出處理。
IHttpHandler接口中最重要的方法ProcessRequest,這個方法就是HttpHandler用來處理一個Http請求,當一個Http請求經過由HttpModule容器傳遞到HttpHandler容器中的時候,framework會調用HttpHandler的ProcessRequest方法來做對這個Http請求做真正的處理。
framework實際上並不是直接把相關頁面的HTTP請求定位到一個內部默認的IHttpHandler容器之上的,而是定位到了其 內部默認的IHttpHandler Factory上了。IHttpHandler Factory的作用就是對很多系統已經實現了的IHttpHandler容器進行調度和管理的,這樣做的優點是大大增強了系統的負荷性,提升了效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章