僅此一文讓你明白ASP.NET MVC原理

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

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

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

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

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,進行請求的真正處理。

執行時序圖以下圖所示:ui

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

 

UrlRoutingModule的代碼以下:this

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激活裏面,相關類關係以下圖所示:spa

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

 

同URL路由同樣,MVC初始化時,也須要註冊控制器的一些信息,這裏是要讓框架知道默認的控制器工廠是什麼,因此在Application_Start中:.net

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

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

  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傳回到客戶端!!

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

相關文章
相關標籤/搜索