ASP.NET的底層體系2

文章引導

               1.ASP.NET的底層體系1html

               2.ASP.NET的底層體系2 web

引言

             接着上一篇ASP.NET的底層體系1咱們繼續往下走安全

一.System.Web.HttpRuntime.ProcessRequestInternal

             咱們看看ProcessRequestInternal的ProcessRequest多線程

                          1.爲請求建立一個新的HttpContext實例app

                          2.獲取一個HttpApplication實例ui

                          3.調用HttpApplication.Init()初始化管道事件this

                          4.Init()觸發HttpApplication.ResumeProcessing(),啓動ASP.NET管道處理spa

             一個新的HttpContext對象被建立,給它傳遞一個封裝了ISAPI ECB的ISAPIWorkerRequest。HttpContext對象還包含一個很是有用的列表集合,你能夠用它存儲有關特定的請求須要的數據。上下文對象建立於一個請求生命週期的開始,在請求結束時被釋放。所以保存在列表集合裏的數據僅僅對當前的請求有效。.net

                  

 二.HttpApplication

             每個請求都將被路由到一個HttpApplication對象,HttpApplication類會爲你的ASP.NET程序建立一個HttpApplication對象池,它負責加載程序和給每個請求分發HttpApplication的引用,這個HttpApplication對象池的大小能夠經過machine.config的ProcessModel節點中的MaxWorkerThreads選項配置。線程

             HttpApplication對象池儘管以比較少的項目開始啓動,可是同時有多個請求須要處理時,池中的對象也會隨之增長。對於你的WEB程序而言,HttpApplication是一個外部容器,它對應到Global.asax文件定義的類。基於標準的web程序,它是你實際能夠看到的HTTP運行時的第一個登陸點。

             HttpApplication主要用於HTTP管道的事件控制器,它的接口主要由事件構成。

                          BeginRequest

                          AuthenticateRequest

                          AuthorizeRequest

                          ResolveRequestCache

                          AcquireRequestState

                          PreRequireState

                          PostRequestHandlerExecute

                          ReleaseRequestState

                          UpdateRequestState

                          EndRequest

            每個ASP.NET WEB程序運行在各自的AppDomain裏,在AppDomain裏同時運行着多個HttpApplication,這些實例存放在ASP.NET管理的一個HttpApplication對象池裏。

             觀察AppDomain ID一致保持不變,而線程和HttpAapplication的ID在請求多的時候發生改變,這是由於HttpApplication是在一個集合裏運行,下一個請求可能會再次使用同一個HttpApplication實例,因此有時候HttpApplication的ID會重複,一個HttpApplication實例對象並不依賴一個特定的線程,他們僅僅是被分配給處理當前請求的線程而已。

             線程由.NET的ThreadPool提供服務,默認狀況下,線程模型爲多線程單元(MTA),你能夠經過在ASP.NET的頁面的@Page指令裏設置屬性ASCOMPAT="true"覆蓋線程單元的狀態。ASPCOMPAT意味着COM組件將在一個安全的環境下運行。實際上,這些HttpApplication對象運行在同一個AppDomain裏是很重要的,這就是Asp.net如何保證web.config的改變或者單獨的ASP.NET頁面獲得驗證能夠貫穿整個AppDomain。改變web.config的值致使AppDomain的從新開啓。這確保了全部的HttpApplication實例能夠看到這些改變,這是由於當AppDomain從新加載的時候,來自ASP.NET的那些改變將會在AppDomain啓動的時候從新讀取,當AppDomain從新啓動的時候任何靜態的引用都將從新加載。

             這些改變將引發Web程序從新啓動,對於已經存在於處理管道的請求,將繼續經過原來的管道處理,而對於那些新的請求,將被路由到新的AppDomain裏,爲了處理這些「掛起的請求」,在這些請求超時結束以後,ASP.NET將強制關閉AppDomain甚至這些請求該沒有處理。所以在一個特定的時間上,同一個HttpApplication實例在兩個AppDomain裏存在是有可能的。

             HttpApplication負責請求的傳輸,經過觸發事件,通知應用程序正在發生的事情。這個是做爲HttpApplication.Init()方法的一部分實現的(System.Web.HttpApplication.InitInternal和HttpApplication.ResumeSteps())。在這個方法裏,建立和啓動了一系列事件,包括綁定事件處理器,Global.asax裏的事件處理器會自動映射到對應的事件。

             經過在web.config裏註冊,HttpModules和HttpHandlers能夠被動態的加載,而且能夠添加到事件鏈條上,HttpModules實際就是事件處理器,能夠勾住指定的HttpApplication的事件,而HttpHandlers就是一個端點,能夠被調用處理「應用程序級的請求處理」。

             HttpApplication自己不知曉發送給WEB程序的數據,它只是個跑腿的,它是個事件的容器,負責事件之間的通訊,傳遞HttpContext對象。

                 

             ASP.NET管道一旦成功,HttpApplication將逐一觸發事件,每個事件將被觸發,若是事件綁定了事件處理器,那麼這些事件處理器將被調用,執行他們的任務。這個過程的目的是經過調用HttpHandler處理指定的請求,對於ASP.NET而言,HttpHandler是處理請求機制的核心。ASP.NET的頁面和web Service都是HttpHandler的具體實現。HttpModule傾向於在分發給事件處理器以前和以後對內容進行處理

三.HttpModule

             模塊的本質是過濾器,在功能上相似ASP.NET請求級別的ISAPI過濾,對於每個穿過ASP.NET的HttpApplication對象的請求,模塊都容許在HttpApplication對象觸發的事件處理方法裏截獲這些請求,這些模塊以類的形式存儲在外部程序集裏,能夠在web.config裏配置。當程序啓動的時候加載,經過實現指定的接口和方法,模塊就能夠被添加在HttpApplication的事件鏈上,多個HttpModules能夠勾住相同的事件,事件發生的順序跟他們在web.confg裏配置順序。

             <configuration>

                    <sysytem.Web>

                          <HttpModules>

                                 <add name="BasicAuthModule" type="HttpHandlers.BasicAuth,WebStore"/>

             模塊容許你查看每個傳入的web請求,基於觸發的事件基礎上執行操做。模塊是很是有用的,它能夠修改請求,輸出響應的內容以及提供自定義的身份驗證。另外能夠在特定的程序裏,針對ASP.NET的每個請求提供響應前處理和響應後處理。 

             HttpModule相似ISAPI的感受,因爲他們查看進入ASP.NET程序的每個請求,但它們的侷限性僅查看映射到某一個ASP.NET程序或虛擬目錄的請求和映射到ASP.NET的請求,所以你能夠查看全部的ASPX頁面或者任意其餘自定義的已經映射到這個程序的擴展名。

             實現一個HttpModule模塊,它包含兩個方法:Init()和Dispose(),傳遞的事件參數中包含一個HttpApplication對象的引用,它會給你HttpContext的訪問權限。

public class BasicAuthCustomModule : IHttpModule
{

   public void Init(HttpApplication application)
   {
      // *** Hook up any HttpApplication events
      application.AuthenticateRequest += 
          new EventHandler(this.OnAuthenticateRequest);
   }
   public void Dispose() { }

   public void OnAuthenticateRequest(object source, 
                                   EventArgs eventArgs)
   {
      HttpApplication app = (HttpApplication) source;
      HttpContext Context = HttpContext.Current;
      … do what you have to do…                     } 
}

             在Init()方法裏,你能夠勾住多個事件,所以在一個模塊裏,能夠管理多個不一樣功能的操做。在HttpModules裏使用HttpApplication的事件時,Response.End()和HttpApplication.CompleteRequest()方法會使ASP.NET跳過HttpApplication和模塊的事件鏈。

四.HttpHandler

             HttpModule針對每個傳入ASP.NET程序的請求觸發,HTTPHandler重於處理一個指定的請求映射。HttpHandler繼承IHttpHandler,這個藉口有一個方法ProcessReuqest()和一個屬性IsReusable。ProcessRequest()能夠獲取一個HttpContext。

             HttpHandler的關鍵操做是往Response對象裏寫輸出數據,或者更確切的說,是往Response對象的OutputStream裏寫,這個就是真正返回到客戶端的輸出數據,在底層,由ISAPIWorkerRequest負責把OutputStream發回給ISAPI的ecb.WriteClient方法,由於ecb.WriteClient纔是真正執行IIS產生輸出數據的。

             

相關文章
相關標籤/搜索