仅此一文让你明白 ASP.NET MVC 原理

ASP.NET MVC 由以下两个核心组成部分构成:

  1. 一个名为 UrlRoutingModule 的自定义 HttpModule,用来解析 Controller 与 Action 名称;
  2. 一个名为 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 拦截,拦截后执行流程如下:

  1. 封装当前 http 上下文,变为 HttpContextWrapper 对象。
  2. 根据当前的 http 上下文,从 Routes 中得到与当前请求 URL 相符合的 RouteData 对象。该对象存储有 RouteHandler 信息。
  3. 把 RouteData 与 http 上下文请求封装成一个 RequestContext 对象。
  4. 根据 RequestContext 对象,从 RouteData 的 RouteHandler 中获取 IHttpHandler。
  5. 执行 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 的激活:

  1. 从 Requestcontext 封装的 RouteData 中得到 Controller 名字。
  2. 通过 ControllerBuilder 得到当前默认的 Controller 工厂。
  3. 根据 Controller 的名字,创建控制器对象(在 ControllerFactory 初始化的时候,会扫描整个程序集中所有实现 IController 接口的控制器类型,所以当调用CreateController 时,实际上是直接获取)。
  4. 最后执行控制器。执行的实质其实就是执行 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,并得到ActionResult
17     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 学习!!!!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。