概念:ISAPI 伺服器擴充是可以被 HTTP 伺服器載入和調用的 DLL。
1.當asp.net頁面發起請求時,IIS收到請求會根據請求頁面的尾碼名,交給相應的ASP.NET ISAPI做處理,
2.ASP.NET ISAPI安排aspnet_wp.exe處理請求,並監視aspnet_wp.exe(w3wp.exe iis 6)進程的執行情況。
3.aspnet_wp.exe的主要任務是將請求交給一系列稱為的 HTTP 管道的託管對象
恰當的比喻:
如果把ASP.NET ISAPI比做銷售經理,那aspnet_wp.exe就是生產經理,而HTTP 管道就是生產的流水線。
負責流水線的小組就是HttpRuntime,生產經理aspnet_wp.exe會將訂單(HTTP請求)交給HttpRuntime小組的工作人員ProcessRequest(HttpWorkerRequest wr),HttpRuntime根據內部的分工,最終由ProcessRequestInternal(HttpWorkerRequest wr)在流水線上進行生產,所以ProcessRequestInternal(HttpWorkerRequest wr)是我們分析的重點。
ProcessRequestInternal的主要工作是:
1. 建立HttpContext執行個體
2. 對第一次請求進行初始化(EnsureFirstRequestInit)。
3. 建立HttpWriter執行個體。
4. 通過調用HttpApplicationFactory.GetApplicationInstance建立HttpApplication執行個體。
建立HttpApplication執行個體之後就是調用執行個體的InitInternal方法。
InitInternal方法主要功能如下:
4.1 InitModules():根據Web.Config的設定,建立相應的HttpModules。
4.2 HookupEventHandlersForAppplicationAndModules:根據發生的事件,調用HttpApplication執行個體中相應的事件處理函數。
4.3建立很多實現IExecutionStep介面的類的執行個體並添加到當前HttpApplication執行個體的_execSteps中,等待回調時執行。
5. 調用HttpApplication執行個體的BeginProcessRequest非同步處理請求。
詳見:http://www.cnblogs.com/aaa6818162/archive/2009/11/13/1602333.html
1,當接收到一個HTTP請求
2,通過iis中的isapi從 http.sys中擷取當前的htttp的請求資訊,並且將這些資訊儲存到 HttpWorkerRequest 類中
3,在相互隔離的應用程式定義域AppDomain中載入HttpRuntime。 調用 HttpRuntime的ProcessRequest方法( 方法參數HttpWorkerRequest )
4,Http請求進入 HttpRuntime以後
5. HttpRuntime將Http請求轉交給 HttpApplication,HttpApplication代表著程式員建立的Web應用程式。
HttpApplication建立針對此Http請求的 HttpContext對象,這些對象包含了關於此請求的諸多其他對象,主要是HttpRequest、HttpResponse、HttpSessionState等。這些對象在程式中可以通過Page類或者Context類進行訪問。、
6. 接下來Http請求通過一系列Module,這些Module對Http請求具有完全的控制權。
這些Module可以做一些執行某個實際工作前的事情。
7. Http請求經過所有的Module之後,它會被HttpHandler處理。
在這一步,執行實際的一些操作,通常也就是.aspx頁面所完成的商務邏輯。
public class Page : TemplateControl, IHttpHandler{
// 代碼省略
}
可以看到,Page類實現了IHttpHandler介面,HttpHandler也是Http請求處理的最底層。
8.HttpHandler處理完以後,Http請求再一次回到Module,此時Module可以做一些某個工作已經完成了之後的事情。
9.然後,IIS 接收返回的資料流,並重新返還給 HTTP.SYS,
10最後,HTTP.SYS 再將這些資料返回給用戶端瀏覽器。
在建立好HttpApplication後注意的一些事情
HttpModule和HttpHandler兩者都是在HttpApplication.Init()函數調用的一部分中被載入並附加到調用鏈上
//在添加所有事件處理常式模組之後執行自訂初始化代碼。
HttpApplication public virtual void Init();
總的來說
1先通過 httpapplication的initinternal方法,初始化各個module
2再通過httpapplication下的applicationstepmanager的buildestep方法 (按順序建立各個步驟)
3httpapplication的beginprocessrequest方法執行建立起來咯各個步驟,即觸發httpapplication的生命週期
httphandel和httpmodel的執行關係
表 1:HttpApplication 對象激發的事件
| 事件 |
備忘 |
BeginRequest |
在請求處理開始之前激發 |
AuthenticateRequest |
驗證調用方的身份 |
AuthorizeRequest |
執行訪問檢查 |
ResolveRequestCache |
從緩衝中擷取響應 |
AcquireRequestState |
載入工作階段狀態 |
PreRequestHandlerExecute |
在請求即將發送到處理常式對象之前激發 |
PostRequestHandlerExecute |
在請求剛剛發送到處理常式對象之後激發 |
ReleaseRequestState |
儲存工作階段狀態 |
UpdateRequestCache |
更新響應緩衝 |
EndRequest |
在處理結束後激發 |
PreSendRequestHeaders |
在發送緩衝的響應標題之前激發 |
PreSendRequestContent |
在發送緩衝的響應本文之前激發 |
注意:HTTP 處理常式(HttpHandler)在 PreRequestHandlerExecute 和 PostRequestHandlerExecute 事件之間執行。
HttpApplication是HttpRuntime所建立的嗎? 並不是,HttpRuntime只是向HttpApplicationFactory提出請求,要求返回一個HttpApplication對象。HttpApplicationFactory在接收到請求後,會先檢查是否有已經存在並閒置對象,如果有就取出一個HttpApplication對象返回給HttpRuntime,如果沒有的話,則要建立一個HttpApplication對象給HttpRunTime。
關於HttpApplication這個類的方法的實現,就不再一一解釋,需要瞭解的,在類裡面寫上一個HttpApplication單詞,然後右鍵選擇“轉到定義“,就可以看到裡面的中繼資料了。
參考備忘:
ASP。NET的設計思想 http://www.cnblogs.com/aaa6818162/archive/2009/10/30/1592886.html#1688909
HttpApplication的認識與加深理解 http://www.cnblogs.com/whtydn/archive/2009/10/16/1584584.html
asp.net原理 《重要》 http://www.cnblogs.com/aaa6818162/archive/2009/11/11/1600987.html