asp.net 處理流程
在iis中,工作進程(w3wp.exe)運行著asp.net應用程序,管理並響應所有的請求,asp.net所有的功能都運行在工作進程下,當請求到來時,工作進程會生成request和response相關信息。
應用程序池:
應用程序池是工作進程的容器。通常用來隔開不同配置的工作進程,當一個程序出錯或進程資源回收的時,其他池中的程序不受影響。
註:當一個應用程序池包含多個工作進程時,叫做web garden
如果我們看看iis 6 的結構,就會發現可以把他分為兩部分
內核模塊(kernel model)
用戶模塊(user model)
內核模式是從iis 6.0被引入的,他包含一個叫做http.sys的文件,每當請求到來時,會首先觸發該文件的響應。
http.sys負責將請求傳入到相應的應用程序池,但是http.sys是如何知道應該傳到那個應用程序池?當然不是隨機的,每當創建一個應用程序池,該池的ID就會生成並在http.sys文件中註冊,因此該文件就能確定將請求發往那個程序池。
以上便是IIS處理請求的第一步。接著,我們來看一下請求如何從HTTP.SYS傳入應用程序池。
在iis用戶模塊(user model),通過WAS(web admin services)從http.sys接收請求,並傳入應用程序池。
當應用程序池接收到請求之後,會傳給工作進程(w3wp.exe),該進程檢查請求的URL後綴,以確定載入那個ISAPI 擴展,然後將該請求傳遞給合適的 ISAPI 擴展。
ASP.NET 處理已映射到它上的文件擴展名,如 .aspx、.ascx、.ashx 和 .asmx。
即:當文件為上述後綴時,就要載入ASP.NET的ISAPI擴展(aspnet_isapi.dll)
一旦工作進程載入了aspnet_isapi.dll,就會構造一個HttpRuntime類(密封類,防止派生),該類是應用程序的入口,通過該類中的ProcessRequest()方法創建HttpContext類,進入ProcessRequest方法之後,內部觸發一系列的方法,最終創建一個HttpContext實例(可通過HttpContext.Current獲取到這個實例),且該實例會在整個生命周期內存活。
之後HttpRuntime類會向HttpApplicationFactory類 提出請求,要求返回一個HttpApplication對象,HttpApplicationFactory在收到請求之後會檢查是否有已經存在並且空閑的對象,如果有就取出一個HttpApplication對象返回給HttpRuntime類,如果沒有,則要創建一個給HttpRuntime。
HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context) 該方法創建HttpApplication實例並進行初始化,調用System.Web.HttpApplication.InitInternal()方法。
當每次請求到來時要穿過httpModule到達httphandler,以便被響應。而httpmodule就被配置在httpApplication中。
創建HttpApplication實例之後就是調用實例的InitInternal方法。
InitInternal方法的主要功能如下:
1、HttpAplication對象被初始化時,首先調用InitModule方法來載入Web.config文件中配置的所有HttpModule模塊。
例如:
//Web.Config文件中<System.web> <httpModules> <add name="MyModuleName" type="MyModule"> </httpModules></System.web>//自定義一個類(類型)public class MyModule:IHttpModule{ public MyModule() { // // TODO: 在此處添加構造函數邏輯 // } #region IHttpModule 成員 public void Dispose() { } public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Mycontext_BeginRequest); } private void Mycontext_BeginRequest(object sender, EventArgs e) { //具體操作 HttpContext.Current.Response.Write("BeginRequest11111111111111</br>"+dt); } #endregion}
2、接著HookEventHandlesForApplicationAndModules方法被調用,這個方法完成Global.asax文件中配置的HttpModule或HttpApplication的綁定。
例如:
//Global.asax文件 void MyModule_ExposedEvent(object sender, EventArgs e) { Response.Write("xixi"); }
//MyModule.cs文件public class MyModule:IHttpModule { public event EventHandler ExposedEvent;//HttpModule事件,供Global.asax來訂閱 public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest);//訂閱HttpApplication的事件 } void context_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.Write("BeginRequest"); OnExposedEvent(new EventArgs());//觸發HttpModule自定義事件 } protected void OnExposedEvent(EventArgs e) { if (ExposedEvent != null) { ExposedEvent(this, e); } } public void Dispose() { } }上面的MyModule_ExposedEvent方法就會自動訂閱了MyModule中的ExposedEvent事件。
3、最後ApplicationStepManage對象的BuildSteps方法被調用,完成HttpApplication事件的綁定。
4、按照順序執行HttpApplication的各個事件。即:之前註冊的對請求加以處理或者檢查的HttpModule模塊內容也得以執行。
在這些事件中,第10個事件【根據所請求資源的文件擴展名(在應用程序的配置文件中映射),選擇實現 IHttpHandler 的類,對請求進行處理】,這個事件也是HttpHandler創建的地方。
-----------------------------------------------------------------
前面我們一直在說ASP.NET管線,那麼,誰在控制管線過程?答案是:HttpApplication對象。1. HttpApplication細分它的處理過程,在不同階段引發不同的事件,使得HttpModule通過訂閱事件的方式加入到請求的處理過程中。2. 在請求的處理過程中,HttpApplication對象主要扮演著控制處理流程的推進作用。3. HttpApplication會在固定的階段獲取一個IHttpHandler實例,然後將請求的響應過程交給具體的IHttpHandler來實現。
HttpApplication如何產生,如何工作?1. HttpApplication對象會被重用,當HttpRuntime不能從HttpApplicationFactory獲取空閑的實例時,才會創建。2. HttpRuntime會將每個請求交給一個HttpApplication對象來處理。3. HttpApplication對象在初始化時負責載入全部的HttpModule。4. 每個HttpApplication對象會控制屬於它的管線過程。
HttpApplication是個非常重要的類型,它的許多功能都屬於框架的基礎部分,不需要我們調用, 因此,我們平時不會用到它。
-------------------------------------------------------------------------
HttpHandler根據用戶請求的文件的擴展名(.aspx、.ascx、.ashx 、 .asmx)處理請求。
HttpApplication在將某個請求交給HttpHandler實例來處理時,是通過介面來調用某個合適HttpHandler類中ProcessRequest方法,來處理請求。
例如:自己定義個處理請求的HttpHandler。 (其實HttpHandler是只實現了IHttpHandler介面的類總稱)
//Web.Config文件中<httpHandlers> <add path="*.aspx" verb="*" type="SearchInfo.Handle"/> <add path="*.ascx" verb="*" type="SearchInfo.Handle2"/></httpHandlers>//SearchInfo是命名空間,Handle是自己定義處理請求的類。//即:當一個請求Url後綴是 .aspx 時,就會交給自定的Handle類去處理namespace SearchInfo{ /// <summary> /// Handle 的摘要說明 /// </summary> public class Handle:IHttpHandler { public Handle() { // // TODO: 在此處添加構造函數邏輯 // } #region IHttpHandler 成員 public bool IsReusable { get { throw new Exception("The method or operation is not implemented."); } } public void ProcessRequest(HttpContext context) { HttpContext.Current.Response.Write("自定義Handler處理請求aspx"); } #endregion }}
所以,我們應該這樣理解HttpHanlder:一個HttpHanlder用於響應一類特定的請求。
在請求的處理過程中,HttpApplication對象主要扮演著控制管線處理流程的作用,它負責推進整個處理流程, 除了在不同階段引發不同的事件外(供HttpModule使用),HttpApplication對象還會根據當前請求尋找一個合適的IHttpApplicationFactory實例, 並最終得到一個IHttpHandler的實例用於處理請求。
當每次請求到來時要穿過httpModule到達httphandler,以便被響應。而httpmodule就被配置在httpApplication中。
即流程為:
每當請求Web伺服器上的某些信息時,該請求首先會到達Http.SYS,然後Http.SYS將其發送到相應的應用程序池,應用程序池傳給工作進程並載入ISAPI擴展,然後HttpRuntime對象會被創建,並通過HttpModule和HttpHandler處理請求。
對於詳細的HttpHandler和HttpModule可以在 Fish Li 的博客中:
推薦閱讀:
※【註銷指南】簡易註銷流程!!
※深加工結轉操作流程
※必讀︱辦理護照換髮流程全解析
※PIC豬場配種、產房管理操作流程(超一萬字,十分詳細)