1. 程式人生 > >Asp.Net高級知識回顧_HttpModule及應用程序生命周期_1

Asp.Net高級知識回顧_HttpModule及應用程序生命周期_1

應用 性能 枚舉 常用 進入 sdn 理解 bsp 管線

為什麽asp.net落後了,還講這些?因為mvc 還是沿用老框架的,加了一個請求模塊,在第七個事件中觸發;

一、概念

HTTP模塊(HttpModule)是通過實現IHttpModule接口和處理事件,在每次針對應用程序發出請求時調用的程序集。HTTP模塊作為ASP.NET請求管線的一部分調用,能夠在整個請求過程中訪問生命周期事件。因此,HTTP模塊使我們有機會檢查傳入和傳出的請求,並根據該請求采取操作,甚至我們可以通過實現HTTP模塊來參與ASP.NET的運行管理。

二、托管管道模式(IIS應用程序池)

1. 經典模式

在IIS7之前,ASP.NET是以IIS ISAPI Extension的方式外加到IIS。

然後IIS根據要求的內容類型做判斷,如果是HTML靜態網頁就由IIS自行處理,如果不是,就根據要求的內容類型,分派給各自的IIS ISAPI Extension,如果要求的內容類型是ASP.NET,就分派給負責處理ASP.NET的IIS ISAPI Extension,也就是aspnet_isapi.dll。IIS7應用程序池托管管道模式中的“經典模式”也是這樣的工作原理,這種模式是兼容IIS 6的方式,以減少升級成本。下圖是這個架構的示意圖:

技術分享圖片

2. 集成模式

IIS7完全整合 .NET 之後,架構的處理順序有了很大不同,最大變化是ASP.NET從IIS插件(ISAPI Extension)的角色進入了 IIS 核心,並且能以ASP.NET模塊處理IIS7的諸多類型要求。這些ASP.NET模塊不只能處理ASP.NET網頁程序,也能處理其他程序;看圖吧:

技術分享圖片

3. IIS5、IIS6中的生命周期,處理順序

技術分享圖片

a. 用戶從Web服務器請求應用程序資源。

ASP.NET應用程序的生命周期以瀏覽器向Web服務器(對於ASP.NET應用程序,通常為IIS)發送請求為起點。ASP.NET是Web服務器下的ISAPI擴展。Web服務器接收到請求時,會對所請求文件的文件擴展名進行檢查,確定應由哪個ISAPI擴展處理該請求,然後將該請求傳遞給合適的ISAPI擴展。ASP.NET處理已映射到其上的文件擴展名,如.aspx、.ascx、.ashx 和 .asmx。

如果文件擴展名尚未映射到ASP.NET,則ASP.NET將不會接收該請求。對於使用ASP.NET身份驗證的應用程序,理解這一點非常重要。 例如.htm 文件,通常沒有映射到ASP.NET,因此ASP.NET將不會對.htm 文件請求執行身份驗證或授權檢查,因此,即使文件僅包含靜態內容,想要 ASP.NET 檢查身份驗證,應使用映射到ASP.NET的文件擴展名創建該文件,如采用.aspx文件擴展名。

如果要創建服務於特定文件擴展名的自定義處理程序(httphandler),必須在IIS中將該擴展名映射到ASP.NET,還必須在應用程序的Web.config文件中註冊該處理程序。

b.ASP.NET接收對應用程序的第一個請求。

當ASP.NET接收到對應用程序中任何資源的一個請求時,名為ApplicationManager的類會創建一個應用程序域。www站點運行於其中。我們都知道,在同一個IIS上,兩個web應用程序的應用程序域都是獨立的(隔離的)。因此一個應用程序域中問題不會影響到其它應用程序域。在應用程序域中,將為名為 HostingEnvironment的類創建一個實例,該實例提供有關應用程序的信息(如存儲該應用程序的文件夾名稱)訪問。

下面的關系圖說明了這種關系:

技術分享圖片

c. 為每個請求創建ASP.NET核心對象。

創建應用程序域並對HostingEnvironment對象進行了實例化之後,ASP.NET將創建並初始化核心對象,如HttpContext、HttpRequest和HttpResponse。HttpContext類包含特定於當前應用程序請求的對象,如 HttpRequest和HttpResponse對象。HttpRequest對象包含有關當前請求的信息,包括Cookie和瀏覽器信息。HttpResponse對象包含發送到客戶端的響應,包括所有呈現的輸出和Cookie。

d.將HttpApplication對象分配給請求。

初始化所有核心應用程序對象之後,將通過創建HttpApplication類的實例啟動應用程序。如果應用程序具有Global.asax文件,則ASP.NET將創建Global.asax類(從 HttpApplication 類派生)的一個實例,並使用該派生類表示應用程序。

第一次在應用程序中請求ASP.NET頁或進程時,將創建HttpApplication的一個新實例。為了盡可能提高性能,可對多個請求重復使用HttpApplication實例。

創建HttpApplication的實例時,將同時創建所有已配置的模塊。創建了所有已配置的模塊之後,將調用HttpApplication類的Init 方法。

下面的關系圖說明了這種關系:

技術分享圖片

e: 由HttpApplication管線處理請求。

在處理該請求時將由HttpApplication 類執行HttpModule事件。

4. IIS7中的生命周期
a.發出一個對應用程序資源的請求。

ASP.NET應用程序的生命周期以瀏覽器向Web服務器發送請求為起點。

IIS7.0經典模式下,以及IIS6.0中,ASP.NET請求管道與Web服務器管道分離,模塊僅應用於路由到ASP.NET ISAPI擴展的請求,如果請求資源類型的文件擴展名未顯式映射到 ASP.NET,則不會為該請求調用ASP.NET功能,如靜態文件,原因是ASP.NET運行時沒有處理該請求。

而在IIS7.0集成模式下,由一個統一的管道處理所有請求,當集成管道收到請求時,該請求將經歷所有請求共有的一些階段,這些階段由RequestNotification枚舉表示,所有請求都可以配置為使用ASP.NET功能,該功能封裝在可以訪問請求管道的托管代碼模塊中。例如,即使 .htm文件擴展名未顯式映射到ASP.NET,對HTML頁的請求仍會調用ASP.NET模塊。這使得我們可以對所有資源使用ASP.NET身份驗證和授權。

b. 統一管道接收對應用程序的第一個請求。

當統一管道接收對應用程序中的任何資源的第一個請求時,將為ApplicationManager類創建一個實例,該實例就是處理請求的應用程序域,應用程序域提供了應用程序之間全局變量的分離,並且使每個應用程序能夠單獨卸載。在應用程序域中,將為HostingEnvironment類創建一個實例,該實例提供對有關應用程序的信息(如存儲該應用程序的文件夾的名稱)的訪問。

c. 將為每個請求創建響應對象。

在創建應用程序域並對HostingEnvironment對象進行實例化之後,將創建並初始化應用程序對象,如 HttpContext、HttpRequest和HttpResponse。HttpContext類包含特定於當前應用程序請求的對象,如 HttpRequest和HttpResponse對象。HttpRequest對象包含有關當前請求的信息,包括 Cookie 和瀏覽器信息。HttpResponse對象包含發送到客戶端的響應,其中包括所有呈現的輸出和Cookie。

d.將HttpApplication對象分配給請求。

初始化所有應用程序對象之後,將通過創建HttpApplication類的實例來啟動應用程序。如果應用程序有 Global.asax文件,則ASP.NET將創建從HttpApplication類派生的Global.aspx類的實例。然後使用該派生類來表示應用程序。

第一次在應用程序中請求ASP.NET頁或進程時,將創建HttpApplication類的一個新實例。為了盡可能提高性能,可對多個請求重復使用HttpApplication 實例。

加載哪些ASP.NET模塊取決於應用程序從父應用程序繼承的托管代碼模塊,還取決於在應用程序的Web.config文件的配置節中配置了哪些模塊。在應用程序的Web.config的 system.webServer節中的modules元素中添加或移除模塊。我會專門寫一張文章記錄常用的webconfig

f.由HttpApplication 管線處理請求。

在處理請求時,HttpApplication類會執行一些系列的事件,如果是開發自定義模塊,並且希望對發往管道的所有請求都調用該模塊,則這些事件也很有用。自定義模塊實現IHttpModule接口,在IIS7.0集成模式下,必須在模塊的Init方法中註冊事件處理程序。

Asp.Net高級知識回顧_HttpModule及應用程序生命周期_1