標籤:

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豬場配種、產房管理操作流程(超一萬字,十分詳細)

TAG:流程 | 處理 |