mvc請求管道(一)

1、前言

        在日常作後臺開發的時候,常常會說到請求管道,不少開發者都知道這個,也能說幾句,可能無法詳細的去介紹,今天就來詳細的說一下這個。html

2、到達IIS以前

        請看下面這個流程圖。從用戶打開瀏覽器到請求到達服務器,這些都是須要咱們去配置就好了,這裏面有一些知識點,http/https、tcp/ip、dns解析這些感興趣的能夠去了解一下。web

       

 3、請求到達IIS

         一樣先看流程圖,Sys服務監聽到有請求到達IIS,IIS會把這個請求轉發給ISAPI,ISAPI即Internet Server Application Program Interface (互聯網應用服務接口),是微軟提供的一套面向Internet服務的API接口,它根據後綴判斷須要把該請求轉發給誰處理,.net的請求會轉發到asp.net_ISAPI,它屬於IIS,運行在IIS進程中的,它會用Pipeline的方式把請求轉交給.Net Framework,它很像一個隊列(先進先出),能夠對請求進行排隊處理,在請求處理完,會釋放掉該請求佔用的socket連接。瀏覽器

       

 

 4、請求到達應用程序

           慣例,先上圖。HTTPRuntime.ProcessRequest是整個應用程序的入口,這一步會接收上一步打包的HTTPWorkerRequest,完成HttpContext的初始化,調用HttpApplicaFactory工廠類建立HttpApplication(HttpApplication實現了IHttpHandler),HttpApplicationFactory.GetApplicationInstance建立HttpApplication實例中有三個關鍵方法:
           1. HttpApplicationFactory._theApplicationFactory.EnsureInited()該方法檢查HttpApplicationFactory是否被初始化(它是存放在一個棧裏面的)若是沒有,就經過HttpApplicationFactory.Init()進行初始化。在Init()中,先獲取Global.asax文件的完整路徑,而後調用CompileApplication()對Global.asax進行編譯。
           2. HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context)  建立特定的HttpApplication實例,觸發ApplicationOnStart事件,執行ASP.Global.asax中的Application_Start(object sender, EventArgs e)方法。這裏建立的HttpApplication實例在處理完事件後,就被回收。
           3. HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context) 該方法建立HttpApplication實例並進行初始化,調用System.Web.HttpApplication.InitInternal()方法。建立HttpApplication實例是根據實際的_theApplicationType進行建立。若是Web目錄中沒有global.asa文件,也就是說沒有動態編譯生成ASP.Global.asax類型,那就直接實例化HttpApplication。若是建立了ASP.Global.asax類型,那就對ASP.Global.asax進行實例化。緩存

     

 

 5、請求到達MVC的處理管線

      上面大概介紹了Asp.Net Mvc的請求到達應用程序的管道,接下來就是和咱們編碼息息相關的處理流程了,下面這張圖是我在之前查閱資料的時候保存下來了,出處已經找不到,若是有知道能夠留個言。安全

      當請求到達應用程序以後,第一站就是路由模塊,MVC會根據RouteTable(通常都在RouteConfig中配置,在MVC第一次啓動時,路由系統就會把咱們註冊的路由規則,寫在Glocal.asax中的Application_Start事件中)中配置的路由模板去匹配當前的請求,獲取對應的Controller和Action信息,具體的匹配過程是由UrlRoutingModule(System.Web.Routing.UrlRoutingModule)來實現的。服務器

      當UrlRoutingModule在Route Table中找到一條匹配的路由規則時,就會爲這條路由規則尋找對應的IRouteHandler(System.Web.Mvc.IRouteHandler)實例(默認是System.Web.MvcRouteHandler),根據這個RouteHandler最後獲取一個IHttpHandler的實例(默認是System.Web.MvcHandler)。在處理完路由信息和匹配到以後,就來到了Controller。app

      在MvcHandler中的ProcessRequest方法中就是ASP.NET MVC的生命週期,這個方法使用IControllerFactory的實例(默認是System.Web.Mvc.DefaultControllerFactory)來建立相應的Controller。asp.net

      建立完Controller以後,就會執行Controller的invokeAction()方法,找到合適的Action後,就是Model Binding(默認是System.Web.Mvc.DefaultModelBinder),它會從Http請求的參數中提取數據並實現類型轉換,數據校驗(例如是否必填,數據格式等)以及是否自動裝配到Action方法的參數中。socket

       完成模型綁定以後就是執行Filter了,Filter也是一個能夠鋪開說的知識,這裏先只簡單的介紹一下,從下圖看到第一個是Authentication Filter,它是MVC5中新增的一個Filter,它會先於Authorization Filter執行,目的是對訪問用戶的認證。在MVC5以前,認證和受權都是經過Authorization Filter來實現的。而後是Authorization Filter 這個主要是驗證受權的,受權驗證經過後執行的Action Filter,自定義Action Filter需繼承ActionFilterAttribute,它分爲兩個方法,OnActionExecuting和OnActionExecuted分別在action執行先後執行,咱們能夠經過實現IActionFilter接口來實現你個性化的過濾機制。在Action Filter執行以後,就會執行咱們的業務代碼了。tcp

       在執行完業務代碼,會執行ActionResult,ActionResult也有一個Filter,自定義ActionResult Filter需繼承ActionFilterAttribute它也分爲兩個方法:OnResultExecuting和OnResultExecuted,它是在動做結果被執行以前和以後運行。ActionResult就是把後臺處理的用戶請求結果返回。所以ViewResult、PartialViewResult、RedirectToRouteResult、RedirectResult、ContentResult、JsonResult、FileResult 和 EmptyResult就是具體的返回類型。

      最後還有一個Exception Filter,它只有在當Action執行發生未處理異常的時候執行OnException方法。自定義Exception Filter須要繼承HandleErrorAttribute類,重寫OnException方法。

      在ActionResult執行完成以後,就是View的初始化和渲染了,ViewResult最終是由View Engine經過調用IView的Render()方法來呈現View的,整個處理過程是由IViewEngine(System.Web.Mvc.IViewEngine)來實現的。ASP.Net MVC 默認提供WebForm(.aspx)和Razor(.cshtml)模板引擎,你也能夠經過實現IViewEngine接口來實現你本身的ViewEngine,而後在Application_Start方法中作以下操做:

protected void Application_Start() 
{ 
     //移除全部的View引擎包括Webform和Razor
     ViewEngines.Engines.Clear();
     //註冊你本身的View引擎
     ViewEngines.Engines.Add(new CustomViewEngine());
}

      在頁面裏,咱們能夠直接寫html標籤,也能夠用@Html等來實現。@Html是使用Html Helpers來生成咱們須要的html標籤,固然它也支持自定義和擴展,這樣就能夠解決咱們一些定製化的需求。

 6、總結

      在上面全部的操做都完成以後,IIS會把結果返回給用戶,用戶才能看到他須要的結果。在整個請求管道中,通常分爲19個事件,以下,

事件名稱:

簡單描述:

BeginRequest

在 ASP.NET 響應請求時做爲 HTTP 執行管線鏈中的第一個事件發生

AuthenticateRequest

當安全模塊已創建用戶標識時發生。注:AuthenticateRequest 事件發出信號表示配置的身份驗證機制已對當前請求進行了身份驗證。預訂 AuthenticateRequest 事件可確保在處理附加的模塊或事件處理程序以前對請求進行身份驗證

 

PostAuthenticateRequest

當安全模塊已創建用戶標識時發生。PostAuthenticateRequest 事件在 AuthenticateRequest 事件發生以後引起。預訂 PostAuthenticateRequest 事件的功能能夠訪問由 PostAuthenticateRequest 處理的任何數據

AuthorizeRequest

當安全模塊已驗證用戶受權時發生。AuthorizeRequest 事件發出信號表示 ASP.NET 已對當前請求進行了受權。預訂 AuthorizeRequest 事件可確保在處理附加的模塊或事件處理程序以前對請求進行身份驗證和受權

PostAuthorizeRequest

在當前請求的用戶已獲受權時發生。PostAuthorizeRequest 事件發出信號表示 ASP.NET 已對當前請求進行了受權。預訂PostAuthorizeRequest 事件可確保在處理附加的模塊或處理程序以前對請求進行身份驗證和受權

ResolveRequestCache

當 ASP.NET 完成受權事件以使緩存模塊從緩存中爲請求提供服務時發生,從而跳過事件處理程序(例如某個頁或 XML Web services)的執行

PostResolveRequestCache

在 ASP.NET 跳過當前事件處理程序的執行並容許緩存模塊知足來自緩存的請求時發生。)在 PostResolveRequestCache 事件以後、PostMapRequestHandler 事件以前建立一個事件處理程序(對應於請求 URL 的頁

PostMapRequestHandler

在 ASP.NET 已將當前請求映射到相應的事件處理程序時發生。

 

AcquireRequestState

當 ASP.NET 獲取與當前請求關聯的當前狀態(如會話狀態)時發生。

 

PostAcquireRequestState

在已得到與當前請求關聯的請求狀態(例如會話狀態)時發生。

 

PreRequestHandlerExecute

剛好在 ASP.NET 開始執行事件處理程序(例如,某頁或某個 XML Web services)前發生。

 

PostRequestHandlerExecute

在 ASP.NET 事件處理程序(例如,某頁或某個 XML Web service)執行完畢時發生。

 

ReleaseRequestState

 

在 ASP.NET 執行完全部請求事件處理程序後發生。該事件將使狀態模塊保存當前狀態數據。

 

PostReleaseRequestState

 

在 ASP.NET 已完成全部請求事件處理程序的執行而且請求狀態數據已存儲時發生。

 

UpdateRequestCache

 

當 ASP.NET 執行完事件處理程序以使緩存模塊存儲將用於從緩存爲後續請求提供服務的響應時發生。

 

PostUpdateRequestCache

 

在 ASP.NET 完成緩存模塊的更新並存儲了用於從緩存中爲後續請求提供服務的響應後,發生此事件。

 

LogRequest

 

在 ASP.NET 完成緩存模塊的更新並存儲了用於從緩存中爲後續請求提供服務的響應後,發生此事件。

僅在 IIS 7.0 處於集成模式而且 .NET Framework 至少爲 3.0 版本的狀況下才支持此事件

 

PostLogRequest

 

在 ASP.NET 處理完 LogRequest 事件的全部事件處理程序後發生。

僅在 IIS 7.0 處於集成模式而且 .NET Framework 至少爲 3.0 版本的狀況下才支持此事件。

 

EndRequest

 

在 ASP.NET 響應請求時做爲 HTTP 執行管線鏈中的最後一個事件發生。

在調用 CompleteRequest 方法時始終引起 EndRequest 事件。

 

 寫的可能不是十分詳細,基本也差很少了,若是有什麼不對的地方歡迎指正。

相關文章
相關標籤/搜索