asp.net MVC 应用程序的生命周期
首先我們知道http是一種無狀態的請求,他的生命周期就是發出請求開始,到得到響應結束。那么MVC應用程序從發出請求到獲得響應,都做了些什么呢?
? ? ? 本文我們會詳細討論MVC應用程序的生命周期和一個請求,從一個控件到另一個控件是怎樣被處理的。我們還會詳細介紹一下整個請求的生命周期中,用到的相關組件。在平常的開發過程中,我們可能知道怎樣去使用MVC框架來處理相關的請求,大部分的時候我們只是在controller和action方法之間做相關的處理。
當我最開始學習使用mvc的時候,困擾我的一個問題就是,一個請求的流程控制是怎樣的呢?從view到controller再到action之間經歷了什么?那個時候我還不清楚HTTP module和HTTP ?handler在處理一個請求中扮演什么樣的角色,起什么樣的作用呢。畢竟MVC是一個web開發框架,肯定包含了http module和http handler在整個請求過程中。其實還有很多相關的組件包含在一個完整的mvc應用程序請求生命周期里,在整個請求過程中他們都扮演者非常重要的角色。盡管大部分時候我們都使用的是框架提供的默認的函數,但是如果我們了解了每個控件所扮演的角色,我們就可以輕松的擴展和使用我們自己實現的方法,就目前來說MVC是擴展性比較強的框架。下面是本章節的主要內容:
UrlRoutingModule
RouteHandler
MvcHandler
ControllerFactory
Controller
ActionInvoker
ActionResult
ViewEngine
先看看下面這張圖,描述了請求管道中的控件和所扮演的角色:
上圖就是一個完整的mvc應用程序的一個http請求到響應的整個兒所經歷的流程。從UrlRoutingModule攔截請求到最終ActionResult執行ExecuteResult方法生成響應。
下面我們就來詳細講解一下這些過程都做了些什么。
?
UrlRoutingModule
MVC應用程序的入口UrlRoutingModule
首先發起一個請求,會被UrlRoutingModule攔截。
從上圖中我們看到UrlRoutingModule實現了接口IHttpModule,所以UrlRoutingModule是一種HttpModule。在這之前,所有的請求還不確定是被誰處理。就是在這個UrlRoutingModule里,決定了這個request是否被MVC應用程序處理。UrlRouting module會從路由表中選擇一個相匹配的路由規則。
那么UrlRouting Module是如何選擇匹配規則的呢?
我們看看我們新建的MVC應用程序,在App_Start文件夾下面有一個RouteConfig.cs類,這個類的內容如下:
我們在這個類里面,主要是給路由表添加路由規則。在看看上面的UrlRoutingModule類,里面有一個RoutCollection屬性,所以UrlRoutingModule能夠獲取路由表中的所有規則,這里值得注意的是,路由規則的匹配是有順序的,如果有多個規則都能夠匹配,UrlRoutingModule至選擇第一個匹配的規則就返回,不再繼續往下匹配了。相反的如果一個請求,沒有匹配到任何路由,那么該請求就不回被處理。
RouteHandler
生成MvcHander
在上面路由匹配的過程中,與匹配路由相關聯的MvcRouteHandler ,MvcRouteHandler 實現了IRouteHandler 接口。MvcRouteHandler 主要是用來獲取對MvcHandler的引用。MvcHandler實現了IhttpHandler接口。
當MvcRouteHandler 被創建的時候,就會調用PostResolveRequestCache()方法。PostResolveRequestCache()方法的定義如下:
PostResolveRequestCache()方法主要做的工作如下:
1、PostResolveRequestCache()是在UrlRoutingModule類里面,UrlRoutingModule類里面有一個RoutCollection屬性,而這個屬性有一個GetRouteData()方法,
我們看到PostResolveRequestCache()方法中恰好調用了GetRouteData()這個方法,然后返回了一個RouteData對象。
2、RouteData里面有一個IRouteHandler類型的屬性RouteHandler?,而調用GetRouteData()返回的RouteData對象里的RouteHandler就是MvcRouteHandler。
3、MvcRouteHandler類有一個GetHttpHandler方法,返回的是一個IHttpHandler類型的對象,返回的就是對MvcHandler對象的引用,綁定到一個MvcHandler的實例。
下面我們就看看MvcHandler做了些什么:
MvcHandler
MvcHandler就是最終對request進行處理。
MvcHandler的定義如下:
我們可以看到MvcHandler就是一個普通的Http ?Handler.我們知道一個http handler需要實現一個ProcessRequest()的方法,這個方法就是處理request的核心。所以MvcHandler實現了ProcessRequest()方法。
ProcessRequest()定義如下:
從上面的代碼可以看出調用了一個ProcessRequestInit()方法,定義如下:
在ProcessRequestInit()方法中首先創建了ControllerFactory()的對象 factory.然后ControllerFactory創建了相關Controller的實例.最終調用了Controller的Excute()方法。
好我們再來看看ControllerFactory:
ControllerFactory
主要是用來生成Controller對象
ControllerFactory實現了接口IControllerFactory.
Controller
?到這里我們大概就知道了,MvcHandler通過ProcessRequest()方法最終創建了Controller對象,這里我們都應該知道,Controller里面包含很多的Action方法,每一次請求至少一個Action方法會被調用。為了明確的實現IController接口,框架里面有一個ControllerBase的類已經實現了IController接口,其實我們自己的Controller也可以不繼承ControllerBase,只要實現IController接口即可。
?
controller對象實際上使用ActionInvoker來調用Action方法的,當Controller對象被創建后,會執行Controller對象的基類ControllerBase類里面的Excute方法。Excute方法又調用了ExcuteCore()方法。Controller類里面實現了ExcuteCore()方法。ExcuteCore調用了ActionInvoker的InvokerAction方法來調用Action方法。
ActionInvoker
ActionInvoker方法有很重要的責任來查找Controller中的Action方法并且調用。
ActionInvoker是一個實現了IActionInvoker接口的對象:
bool InvokeAction(ControllerContext controllerContext, ? ? ? ? ? ? ? string actionName )Controller類里面暴露了一個ActionInvoker?屬性,會返回一個ControllerActionInvoker?。ActionInvoker通過CreateActionInvoker()方法來創建ControllerActionInvoker對象。
我們看到CreateActionInvoker()是一個Virtual方法,我們可以實現自己的ActionInvoker.
ActionInvoker類需要匹配Controller中詳細的Action來執行,而這些詳細的信息是由ControllerDescriptor 提供的。ControllerDescriptor 和ActionDescriptor在ActionInvoker中扮演重要的角色。這兩個分別是對Controler和Action的詳細描述。ControllerDescriptor 描述了Controller的相關信息比如name,action,type等。
ActionDescriptor 描述了Action相關的詳情,比如name,controller,parameters,attributes和fiflters等。
ActionDescriptor?中一個中要的方法就是FindAction(),這個方法返回一個ActionDescriptor 對象,所以ActionInvoker知道該調用哪個Action。
?
?ActionResult
到目前為止,我們看到了Action方法被ActionInvoker調用。所有的Action方法有一個特性,就是返回一個ActionResult類型的數據。
public abstract class ActionResult{ ? ? ?public abstract void ExecuteResult(ControllerContext context);}ExecuteResult()是一個抽象方法,所以不同的子類可以提供不同的ExecuteResult()實現。
ActionResult執行后響應輸出到客戶端。
?
ViewEngine
ViewResult幾乎是大部分應用程序的返回類型,主要通過ViewEngine引擎來展示view的。ViewEngine可能主要就是生成Html元素的引擎。Framwork提供了2種引擎,Razor View Engine 和Web Form?View Engine.如果你想自定義引擎,你可以創建一個引擎只要實現IViewEngine接口即可。
IViewEngine 有下面幾個方法:
1、FindPartialView :當controller需要返回一個PartialView的時候,FindPartialView方法 就會被調用。
2、FindView?
3、ReleaseView :主要用來有ViewEngine釋放資源
ViewResultBase 和ViewResult是比較重要的兩個類。ViewResultBase 包含下面的實現代碼:
當ViewResult的方法ExecuteResult被調用后,ViewResultBase 的ExecuteResult 方法被調用,然后ViewResultBase 調用ViewResult的FindView 。緊接著ViewResult 返回ViewEngineResult,之后ViewEngineResult調用Render()方法來繪制html輸出響應。
總結:如果我們理解了整個過程中發生了什么,哪些類和哪些方法被調用,我們就可以在需要擴展的地方輕松的進行擴展。
原文地址:http://www.cnblogs.com/yplong/p/5582576.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的asp.net MVC 应用程序的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【干货】”首个“ .NET Core 验
- 下一篇: RAML用户应遵循的C#与Web API