ASP.NET MVC生命周期

作者: 堅強2002  來源: 博客園  發布時間: 2009-06-01 16:31  閱讀: 2069 次  推薦: 3   原文鏈接   [收藏]  

Asp.net應用程序管道處理用戶請求時特別強調"時機",對Asp.net生命周期的了解多少直接影響我們寫頁面和控件的效率。因此在2007年和2008年我在這個話題上各寫了一篇文章:

對于Asp.net MVC,我對它的生命周期還是興趣很濃,于是提出兩個問題:

一個HTTP請求從IIS移交到Asp.net運行時,Asp.net MVC是在什么時機獲得了控制權并對請求進行處理呢?處理過程又是怎樣的?

mvcapp 

 

IIS7asp.net應用程序生命周期為例,下圖是來自MSDN的一張HTTP請求處理過程發生事件的簡圖,后面我列出了一個完整的事件列表。既然Asp.net Mvc還是以Asp.net運行時為基礎那么它必然要在Asp.net應用程序的生命周期中對請求進行截獲。第一反應當然是去web.config里面去翻翻,我們可以看到UrlRoutingModule的配置節:

 

      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

 

下面要做的就順理成章了,用Reflector打開這個程序集,可以看到以下代碼:

 

Code

 

看到這里我們的第一個問題實際上已經有了答案:時機是在PostResolveRequestCachePostMapRequestHandler.

 ResolveRequestCache event
Occurs when ASP.NET finishes an authorization event to let the caching modules serve requests from the cache, bypassing execution of the event handler (for example, a page or an XML Web service).

源文檔 <http://msdn.microsoft.com/en-us/library/system.web.httpapplication.resolverequestcache.aspx>

 

 PostMapRequestHandler event
Occurs when ASP.NET has mapped the current request to the appropriate event handler.

源文檔 <http://msdn.microsoft.com/en-us/library/system.web.httpapplication.postmaprequesthandler.aspx>

 

    我們使用VS2008Asp.net Mvc模板創建一個Demo完成后續的討論,當我們訪問/Home的時候發生了什么呢?

  1. Request 請求到來
  2. IIS 根據請求特征將處理權移交給 ASP.NET
  3. UrlRoutingModule將當前請求在 Route Table中進行匹配
  4. UrlRoutingModuleRouteCollection中查找Request匹配的RouteHandler,默認是MvcRouteHandler MvcRouteHandler 創建 MvcHandler實例.
  5.  MvcHandler執行 ProcessRequest.
  6.  MvcHandler 使用 IControllerFactory 獲得實現了IController接口的實例,找到對應的HomeController
  7.  根據Request觸發HomeControllerIndex方法
  8. Index將執行結果存放在ViewData
  9. HomeControllerIndex方法返回 ActionResult
  10. Views/Home/Index.aspx ViewData呈現在頁面上
  11. Index.aspx執行ProcessRequest方法
  12. Index.aspx執行Render方法 輸出到客戶端

 

 

    通過閱讀Asp.net Mvc的源碼,我們可以得到更為詳細的處理過程,我盡可能的忽略掉枝節,強調請求處理的流程.我們從Global.asax.cs文件切入,下面是一段樣例代碼,這里初始化了路由表,請特別特別注意注釋部分:

 

Code

 

UrlRoutingMoudulePostResolveRequestCache階段從RouteCollection中獲取當前請求的RouteData.RouteData包含了一個請求處理對應的ControllerAction,RouteData這個作用貫穿請求的處理過程.RouteData中提取RouteHandler,這里默認是MvcRouteHandler,MvcRouteHandler獲取HttpHandler,這里默認的是MvcHandler.

 

 

PostResolveRequestCache

rh

 

MvcHandler.ProcessRequest()中首先使用HttpContextWrapperHttpContext進行封裝,封裝的目的是為了解耦以獲得可測試性.然后從RequestContext.RouteData中提取Controller名稱.
ControllerBuilder.GetControllerFactory --> ControllerFactory.CreateController --> IController.Execute

ControllerBase實現了IController接口,Initialize時將RequestContext封裝成為ControllerContext,Controller繼承自ControllerBase并實現抽象方法ExecuteCore()

 

mvchttp

 

ExecuteCore,Controller首先從RouteData中獲得ActionName,然后執行ActionInvoker.InvokeAction.

ActionInvoker中我們可以看到各種Filter,這是一種AOP實踐:Action方法執行的前后執行若干方法.這里有四種Filter:ActionFilters,ResultFilters,AuthorizationFilters,ExceptionFilters.這四種Filter并不是封閉的,都有對應的接口,這四個只是默認實現.Filter的執行順序是:AuthorizationFilter--->Action Filter.OnActionExecuting--->Action Method--->ActionFilter.OnActionExecuted.InvokeActionMethodWithFilters返回的結果是ActionExecutedContext,接下來將Controller執行OnResultExecuting 方法.ActionResult執行的結果可以是ViewResult,JsonResult,RedirectResult,ContentResult,或者是自定義的Result類型.

       如果返回的類型是ViewResult,我們先看一下ViewReuslt的繼承關系:ViewResult-->ViewResultBase-->ActionResult,ViewResult包含兩個屬性ViewViewEngineCollection,實際上是包含了兩個接口的實現:IViewEngine定義了怎么定位View/Partial View.IView定義了如何RenderView.默認的實現時WebFormViewWebFormViewEngine.

Filter OnResultExecuted 最后一步了,可以這里捕獲異常.上面我們說過還有ExceptionFilters,如果前面過程中的異常沒有被捕獲那么最終都會到冒泡到ExceptionFilters.

  • RouteData中獲得ActionName
  • ActionInvoker.InvokeAction
  • 通過ControllerContext獲取ControllerDescriptor
  • FindAction-獲取ActionDescriptor
  • GetFilters
  • ModelBinderRequest中的數據轉換成Action方法需要的參數
  • AuthorizationFilter
  • Action Filter.OnActionExecuting
  • Action
  • ActionFilter.OnActionExecuted
  • ResultFilter.OnResultExecuting
  • ActionResult Execution
  • ResultFilter.OnResultExecuted
  • WebFormViewEngine.CreateView
  • WebFormView.Render
  • ResultFilter.OnExecuted

result

 

控制權歸還到HttpApplication完成后續的生命周期.

 

嗯哼,全文完.

 

3
0
 
標簽:MVC
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()