現在敘述最終要的過程,當asp.net在IIS的ISAPI擷取一個aspx的系統請求,並獲得控制權後發生了什麼。
首先,它檢測記憶體中是否有負責處理asp.net內容的運行庫進程(IIS5是aspnet_wp.exe,IIS6是w3wp.exe),如果沒有就建立一個,然後把控制權轉給這個進程(就是函數指標跳轉操作)。
當這個進程接到控制權後,檢查進程裡面的此網站的應用程式設定的應用程式定義域裡面是否有HttpRuntime類的執行個體,沒有就建立一個執行個體。一個伺服器內可以有多個HttpRuntime類的執行個體,原因是一個伺服器的IIS可能建立多個網站,而每個網站可能建立多個虛擬目錄。但是每個網站僅能建立一個HttpRuntime類的執行個體,防止佔用系統資源過多。
HttpRuntime就是asp.net的運行庫程式的基礎了。他負責控制每個網站/虛擬目錄的asp.net請求(注意不是Http請求),但是它不負責處理請求。HttRuntime對象控制的是HttpApplicationFactory對象,它是一個類工廠對象,負責產生類的。
HttpApplicationFactory類負責控制一個對象池,對象池裡面的對象就是我們經常使用的HttpApplication對象。
首先,HttpApplicationFactory負責處理global.ascx程式,並且觸發Application_OnStart事件,然後從池中擷取一個 HttpApplication 執行個體,並將要處理的請求放入執行個體中。如果沒有可用的對象,則建立一個新的 HttpApplication 對象。要建立 HttpApplication 對象,需要先完成 global.asax 應用程式檔案的編譯。然後HttpApplication 開始處理請求,並且只能在完成這個請求後才能處理新的請求。如果收到來自同一資源的新請求,則由池中的其他對象來處理,就是說,如果一個網站有許多使用者,那麼多個使用者的多個請求將由不同的HttpApplication來處理。
應用程式物件允許所有註冊的 HTTP 模組對請求進行預先處理(注意,這就是HttpModule開始工作了),並找出最適合處理請求的處理常式類型。這通過尋找請求的 URL 的擴充和設定檔中的資訊來完成。
所以說,最終處理asp.net頁的是一個名叫HttpApplication的類執行個體。按照上面的步驟就可以得出:當HttpRuntime啟動HttpApplicationFactory的時候,首先啟動的是asp.net自己的事件預先處理程式global.ascx,然後才輪到HttpApplication。
aspx的處理定義系統怎麼知道的?答案就是從machie.config設定檔擷取的。這個檔案定義了所有的.aspx,.ashx,.asmx,.ascx等檔案的處理常式。
結論:處理流程ISAPI --> aspnet_wp.exe/w3wp.exe --> HttpRuntime -->HttpApplicationFactory --> HttpApplication --> 內容Html
那麼,我們是否可以自訂過程處理?可以的,方法就是貼主問的HttpModule(Http模組)和HttpHandle(Http處理器)的作用。
HttpModule就是在HttpApplication處理之前由HttpApplicationFactory啟動並執行global.ascx的事件處理常式的自訂版,它可以讓你自己寫一個繼承IHttpModule介面的類來代替asp.net來處理某個aspx頁,甚至所有的aspx頁,而不由asp.net協助你處理。
而HttpHandler是經過global.ascx處理後所進行內容處理的HttpApplication的代替版,就是說你可以自己寫一個類,繼承IHttpHandler,來代替HttpApplication來處理某個aspx,或者所有的aspx,你可以隨心所欲的來處理aspx的任何內容。不過所有的內容處理必須要你自己寫代碼來處理了,非常方便。