學習ASP.NET MVC5架構揭秘筆記-IIS/ASP.NET管道(三),mvc5-iis

來源:互聯網
上載者:User

學習ASP.NET MVC5架構揭秘筆記-IIS/ASP.NET管道(三),mvc5-iis
ASP.NET管道

以IIS6.0為例,它在背景工作處理序w3wp.exe中會利用aspnet_isapi.dll載入.NET運行時(如果.NET運行時尚未載入)。IIS6.0引入了應用程式進程池的概念,一個背景工作處理序對應著一個應用程式集區。一個應用程式進程池可以承載一個或者多個Web應用,每個Web應用映射到一個IIS虛擬目錄。與IIS5.x一樣,每一個Web應用運行在各自的應用程式定義域中。

如果HTTP.SYS接收到的HTTP請求是對該Web應用的第一次訪問,在成功載入運行時後,IIS會通過AppDomainFactory為該Web應用建立一個應用程式定義域。隨後一個特殊的運行時IsapiRuntime被載入。IsapiRuntime定義在程式集System.Web.dll中,對應的命名空間為“System.Web.Hosting”,被載入的IsapiRuntime會接管該HTTP請求。

接管HTTP請求的IsapiRuntime會首先建立一個IsapiWorkerRequest對象來封裝當前的HTTP請求,隨後將此對象傳遞給ASP.NET運行時HttpRuntime。從此時起,HTTP請求正式進入了ASP.NET管道。HttpRuntime會根據IsapiWorkerRequest對象建立用於表示當前HTTP請求的上下文(Context)對象HttpContext。

隨著HttpContext的建立,HttpRuntime會利用HttpApplicationFactory建立新的或擷取現有的HttpApplication對象。實際上ASP.NET維護著一個HttpApplication對象池,HttpApplicationFactory從池中選取可用的HttpApplication用於處理HTTP請求,處理完畢後將其釋放到對象池中。HttpApplication負責處理當前的HTTP請求。

在HttpApplication初始化過程中,ASP.NET會根據設定檔載入並初始化註冊的HttpModule對象。對於HttpApplication來說,在它處理HTTP請求的不同階段會觸發不同的事件(Event),而HttpModule的意義在於通過註冊HttpApplication的相應事件,將需要的操作注入整個HTTP請求的處理流程。ASP.NET的很多功能都是通過相應的HttpModule實現的。

最終完成對HTTP請求的處理實現在HttpHandler中,不同的資源類型對應著不同類型的HttpHandler。

1.HttpApplication

HttpApplication是整個ASP.NET基礎架構的核心,他負責處理分發給他的HTTP請求。由於一個HttpApplication對象在某個時刻只能處理一個請求,只有完成對某個請求的處理後才能用於後續請求的處理,所以ASP.NET採用對象池的機制來建立或擷取HttpApplication對象。

當第一個請求抵達時,ASP.NET會一次建立多個HttpApplication對象,並將其置於池中,然後選擇其中一個對象來處理請求。處理完畢後,HttpApplication對象不會被回收,而是釋放到池中。對於後續的請求,閒置HttpApplication對象會從池最中取出。如果池中所有的HttpApplication對象都處於繁忙狀態,在沒有超出HttpApplication池最大容量的情況下,ASP.NET會建立新的HttpApplication對象,否則將請求放入隊列等待現有HttpApplication的釋放。

HttpApplication處理請求的整個生命週期是一個相對複雜的過程,在該過程的不同階段會觸發相應的事件。我們可以註冊相應的事件,將處理邏輯注入到HttpApplication處理請求的某個階段。下表按照實現的先後順序列出了HttpApplication在處理每一個請求時觸發的事件名稱。

HttpApplication事件列表

名稱

描述

BeginRequest

HTTP管道開始處理請求時,會觸發BeginRequest事件。

AuthenticateRuest,

PostAuthenticateRequest

ASP.NET先後觸發這兩個事件,使安全模組對請求進行身分識別驗證。

AuthorizeRequest,

PostAuthorizeRequest

ASP.NET先後觸發這兩個事件,使安全模組對請求進行授權。

ResolveRequestCache,

PostResolveRequestCache

ASP.NET先後觸發這兩個事件,以使緩衝模組利用緩衝的內容對請求直接進行響應(緩衝模組可以將響應內容進行緩衝,對於後續的請求,直接將緩衝的內容返回,從而提高響應能力)

PostMapRequestHandler

對於訪問不同的資源類型,ASP.NET具有不同的HttpHandler對其進行處理。對於每個請求,ASP.NET會通過副檔名選擇匹配相應的HttpHandler類型,匹配成功後,該事件觸發

AcquireRequestState,

PostAcquireRequestState

ASP.NET先後觸發這兩個事件,使狀態管理模組擷取基於當前請求相應的狀態,如SessionState

PreRequestHandlerExecute,

PostPreRequestHandlerExecute

ASP.NET最終通過與請求資源相對應的HttpHandler實現對請求的處理,在實行HttpHandler前後,這兩個事件被先後觸發

ReleaseRequestState,

PostReleaseRequestState

ASP.NET先後觸發這兩個事件,使狀態管理模組釋放基於當前請求相應的狀態

UpdateRequestCache,

PostUpdateRequestCache

ASP.NET先後觸發這兩個事件,以使緩衝模組將HttpHandler處理請求得到的內容得以儲存到輸出緩衝中。

LogRequest,

PostLogRequest

ASP.NET先後觸發這兩個事件為當前請求進行日誌記錄

EndRequest

整個請求處理完成之後,EndRequest事件被觸發

對於一個ASP.NET應用來說,HTTPApplication派生於Global.asax檔案,我們可以通過建立Global.asax檔案對HttpApplication的請求處理行為進行定製。Global.asax採用一種很直接的方式實現了這樣的功能,這種方式不是我們常用的方法重寫或事件註冊,而是直接採用方法名匹配。在Global.asax中。我們按照”Application_{Event Name}”這樣的方法命名規則進行事件註冊,比如Application_BeginRequestf方法處理HttpApplication的BeginRequest事件。

2.HttpModule

ASP.NET擁有一個具有高度可擴充性的引擎,並且能夠處理對於不同資源類型的請求。HttpModule功不可沒。

當請求轉入ASP.NET管道時,最終負責處理該請求的是與請求資源類型相匹配的HttpHandler對象,但是在HttpHandler正式工作之前ASP.NET會先載入並初始化所有配置的HttpModule對象。HttpModule在初始化過程中,會將一些回調操作註冊到HttpApplication相應的事件中,在HttpApplication請求處理生命週期中的某個階段,相應的事件會被觸發,通過HttpModule註冊的事件處理常式也得以執行。

所有的HttpModule都實現了具有如下定義的System.Web.IHttpModule介面,其Init方法實現了針對自身的初始化。該方法接收一個HttpApplication對象,有了這個對象,事件註冊就很容易了。

public interface IHttpModule{void Dispose();void Init(HttpApplication context);}


ASP.NET提供的很多基礎功能都是通過相應的HttpModule實現的,下面列出了一些典型的HttpModule,除了這些系統定義的HttpModule之外,我們還可以自訂HttpModule,通過Web.config可以很容易地將其註冊到Web應用中。

(1)OutputCacheModule:實現了輸出緩衝的功能。

(2)SessionStateModule:在無狀態的HTTP協議上實現了基於會話的狀態保持。

(3)WindowAuthenticationModule + FormsAuthenticationModule + PassportAuthenticationModule:實現了Window、Forms和Passport這三種典型的身份認證方式。

(4)UrlAuthorizationModule + FileAuthorizationModule:實現了基於URI和檔案ACL的授權。

3.HttpHandler

對於不同資源類型的請求,ASP.NET會載入不同的Handler來處理。所有的HttpHandler都實現了具有如下定義的介面System.Web.IHttpHandler,定義其中的方法ProcessRequest提供了處理請求的實現。另一個非同步版本的HttpHandler的IHttpAsyncHandler介面繼承自IHttpHandler,它通過調用BeginProcessRequest/EndProcessRequest方法以非同步方式處理請求。

public interface IHttpHandler{void ProcessRequest(HttpContext context);bool IsReusable{get;}}public interface IHttpAsyncHandler : IHttpHandler{IAsyncRequest BeginProcessRequest(HttpContext context,AsyncCallback ch,object extraData);void EndProcessRequest(IAsyncRequest result);}


某些HttpHandler具有一個與之相關的HttpHandlerFactory,定義其中的方法GetHandler用於建立新的HttpHandler或者擷取已經存在的HttpHandler。

public interface IHttpHandlerFactory{IHttpHandler GetHandler(HttpContext context,String requestType,string url,string pathTranslated);void ReleaseHandler(IHttpHandler handler);}


HttpHandler和HttpHandlerFactory的類型都是配置在Web.config來使用的。

除了通過配置建立起HttpHandler類型與請求路徑之間的映射關係之外,我們還可以調用當前HttpContext具有如下定義的RemapHandler方法將一個HttpHandler對象映射到當前HTTP請求。如果不曾通過調用該方法進行HttpHandler的顯示映射,或者調用該方法時傳入的參數為Null,真正的HttpHandler對象的映射發生在HttpApplication的PostMapRequestHandler觸發之前,預設進行HttpHandler的依據就是Web.config的配置。

public sealed class HttpContext{public void RemapHandler(IHttpHandler handler)}


換句話說,在調用當前HttpContext的RemapHandler方法時指定一個具體的HttpHandler對象,是為了讓ASP.NET直接跳過預設的HttpHandler映射操作。由於預設的HttpHandler映射發生在HttpApplication的PostMapRequestHandler事件觸發之前,所以只有在這之前調用RemapHandler方法才有意義。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.