ASP.NET MVC內部請求原理


ASP.NET MVC由以下兩個核心組成部分構成:

  1. 一個名為UrlRoutingModule的自定義HttpModule,用來解析Controller與Action名稱;
  2. 一個名為MvcHandler的自定義HttpHandler,用來實現對Controller的激活和Action的執行;

!!閱讀本文前請先弄明白asp.net執行的流程及httpmodule與httphandler的作用。

下面是進行路由轉換時相關類的簡化結構圖:

http://www.cnblogs.com/DotCpp/

 

 整個ASP.NET MVC系統的路由信息全部存放在RoteTable這個類的靜態變量Routes(為一個RouteDictionary類型)中,網站開始運行時,在Application_Start中對路由進行注冊:

RouteTable.Routes.Add("default", new Route{Url="{controller}/{action}"});

 

當一個URL請求到來時,被UrlRoutingModule攔截,攔截后執行流程如下:

  1. 封裝當前http上下文,變為HttpContextWrapper對象。
  2. 根據當前的http上下文,從Routes中得到與當前請求URL相符合的RouteData對象。該對象存儲有RouteHandler信息。
  3. 把RouteData與http上下文請求封裝成一個RequestContext對象。
  4. 根據RequestContext對象,從RouteData的RouteHandler中獲取IHttpHandler。
  5. 執行IHttpHandler,進行請求的真正處理。

執行時序圖如下圖所示:

http://www.cnblogs.com/DotCpp/

 

UrlRoutingModule的代碼如下:

HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); RouteData routeData = RouteTable.Routes.GetRouteData(httpContext); RequestContext requestContext = new RequestContext{ data = routeData, context= httpContext}; IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext); httpContext.RemapHandler(handler);

 

 經過上面最后一步,執行HttpHandle后,程序正式進入Controller激活里面,相關類關系如下圖所示:

http://www.cnblogs.com/DotCpp/

 

同URL路由一樣,MVC初始化時,也需要注冊控制器的一些信息,這里是要讓框架知道默認的控制器工廠是什么,所以在Application_Start中:

ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory());

程序通過上面的URL路由轉換后,進入HttpHandle中,經過以下步驟實現對Controller的激活:

  1. 從Requestcontext封裝的RouteData中得到Controller名字。
  2. 通過ControllerBuilder得到當前默認的Controller工廠。
  3. 根據Controller的名字,創建控制器對象(在ControllerFactory初始化的時候,會掃描整個程序集中所有實現IController接口的控制器類型,所以當調用CreateController時,實際上是直接獲取)。
  4. 最后執行控制器。執行的實質其實就是執行ActionInvoker.InvokeAction,即根據請求上下文執行相應的Action。

http://www.cnblogs.com/DotCpp/

在自定義的MvcHandler中,代碼如下:

string controllerName =this.Requestcontext.RouteData.Controller; IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
//通過controllerName得到Control(如HomeController) IController controller = controllerFactory.CreateController(this.RequestContext,controllerName); controller.Execute(this.RequestContext);

 

一個典型的IActionInvoker接口實現ControllerActionInvoker的InvokeAction方法如下:

復制代碼
public void InvokeAction(ControllerContext controllerContext, string actionName) { //找到Action方法 MethodInfo method = controllerContext.Controller.GetType().GetMethods() .First(m=>string.Compare(actionName,m.Name,true)==0); //獲取Action參數,並進行Model綁定 List<object> parameters = new List<object>(); foreach(ParameterInfo parameter in method.GetParameters()) { parameters.Add(this.ModelBinder.BindModel(controllerContext, parameter.Name, parameter.ParameterType)); } //執行Action,並得到ActionResult ActionResult actionResult = method.Invoke(controllerContext.Controller, parameters.ToArray()) as ActionResult; //最終ActionResult用HttpResponse將數據傳回客戶進行顯示  actionResult.ExecuteResult(controllerContext); }
復制代碼

最終形成一個Http Response傳回到客戶端!!

大致的過程可以概括如下步驟:

 當請求MVC頁面時,web.config配置文件中的UrlRoutingModule模塊解析該URL,並獲取相關的RouteData對象來創建 HttpHandler的實例MvcHandler,然后在調用MvcHandler的ProcessRequest()方法創建控制器的實例,再執行控 制器的Execute()方法並通過反射機制指定要調用的View()方法來實現頁面內容向瀏覽器推送。

以上即為我整理的ASP.NET MVC的兩個核心流程,希望新手看的明白,老手多多指點其中的問題,謝謝!!有時間會繼續放出MVC其它核心技術。如Model綁定、數據驗證等,同時認真向Artech學習!!!!

 

聲明:此文屬轉載,僅供參考學習;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM