標籤:style blog http io color ar os sp for
ASP.NET MVC 由以下兩個核心組成部分構成:
- 一個名為 UrlRoutingModule 的自訂 HttpModule,用來解析 Controller 與 Action 名稱;
- 一個名為 MvcHandler 的自訂 HttpHandler,用來實現對 Controller 的啟用和 Action 的執行;
!!閱讀本文前請先弄明白 asp.net 執行的流程及 httpmodule 與 httphandler 的作用。
下面是進行路由轉換時相關類的簡化結構圖:
整個ASP.NET MVC系統的路由資訊全部存放在RoteTable這個類的靜態變數Routes(為一個RouteDictionary類型)中,網站開始運行時,在Application_Start中對路由進行註冊:
RouteTable.Routes.Add("default", new Route{Url="{controller}/{action}"});
當一個 URL 請求到來時,被 UrlRoutingModule 攔截,攔截後執行流程如下:
- 封裝當前 http 上下文,變為 HttpContextWrapper 對象。
- 根據當前的 http 上下文,從 Routes 中得到與當前請求 URL 相符合的 RouteData 對象。該Object Storage Service有 RouteHandler 資訊。
- 把 RouteData 與 http 上下文請求封裝成一個 RequestContext 對象。
- 根據 RequestContext 對象,從 RouteData 的 RouteHandler 中擷取 IHttpHandler。
- 執行 IHttpHandler,進行請求的真正處理。
執行時序圖如所示:
UrlRoutingModule 的代碼如下:
1 HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);2 RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);3 RequestContext requestContext = new RequestContext{ data = routeData, context= httpContext};4 IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext);5 httpContext.RemapHandler(handler);
經過上面最後一步,執行 HttpHandle 後,程式正式進入 Controller 啟用裡面,相關類別關係如所示:
同URL路由一樣,MVC初始化時,也需要註冊控制器的一些資訊,這裡是要讓架構知道預設的控制器工廠是什麼,所以在Application_Start中:
ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory());
程式通過上面的 URL 路由轉換後,進入 HttpHandle 中,經過以下步驟實現對 Controller 的啟用:
- 從 Requestcontext 封裝的 RouteData 中得到 Controller 名字。
- 通過 ControllerBuilder 得到當前預設的 Controller 工廠。
- 根據 Controller 的名字,建立控制器對象(在 ControllerFactory 初始化的時候,會掃描整個程式集中所有實現 IController 介面的控制器類型,所以當調用CreateController 時,實際上是直接擷取)。
- 最後執行控制器。執行的實質其實就是執行 ActionInvoker.InvokeAction,即根據請求上下文執行相應的 Action。
在自訂的MvcHandler中,代碼如下:
1 string controllerName =this.Requestcontext.RouteData.Controller;2 IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();3 //通過controllerName得到Control(如HomeController)4 IController controller = controllerFactory.CreateController(this.RequestContext,controllerName);5 controller.Execute(this.RequestContext);
一個典型的 IActionInvoker 介面實現 ControllerActionInvoker 的 InvokeAction 方法如下:
1 public void InvokeAction(ControllerContext controllerContext, 2 string actionName) 3 { 4 //找到Action方法 5 MethodInfo method = controllerContext.Controller.GetType().GetMethods() 6 .First(m=>string.Compare(actionName,m.Name,true)==0); 7 8 //擷取Action參數,並進行Model綁定 9 List<object> parameters = new List<object>();10 foreach(ParameterInfo parameter in method.GetParameters())11 {12 parameters.Add(this.ModelBinder.BindModel(controllerContext,13 parameter.Name, parameter.ParameterType));14 }15 16 //執行Action,並得到ActionResult17 ActionResult actionResult = method.Invoke(controllerContext.Controller,18 parameters.ToArray()) as ActionResult;19 20 //最終ActionResult用HttpResponse將資料傳回客戶進行顯示21 actionResult.ExecuteResult(controllerContext);22 23 }View Code
最終形成一個 Http Response 傳回到用戶端!!
以上即為我整理的 ASP.NET MVC 的兩個核心流程,希望新手看的明白,老手多多指點其中的問題,謝謝!!有時間會繼續放出 MVC 其它核心技術。如 Model 綁定、資料驗證等,同時認真向 Artech 學習!!!!
[轉] 僅此一文讓你明白 ASP.NET MVC 原理