首页 > 代码库 > [转] 仅此一文让你明白 ASP.NET MVC 原理
[转] 仅此一文让你明白 ASP.NET MVC 原理
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 对象。该对象存储有 RouteHandler 信息。
- 把 RouteData 与 http 上下文请求封装成一个 RequestContext 对象。
- 根据 RequestContext 对象,从 RouteData 的 RouteHandler 中获取 IHttpHandler。
- 执行 IHttpHandler,进行请求的真正处理。
执行时序图如下图所示:
UrlRoutingModule 的代码如下:
1 HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);2 RouteData routeData =http://www.mamicode.com/ RouteTable.Routes.GetRouteData(httpContext);3 RequestContext requestContext = new RequestContext{ data = http://www.mamicode.com/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 }
最终形成一个 Http Response 传回到客户端!!
以上即为我整理的 ASP.NET MVC 的两个核心流程,希望新手看的明白,老手多多指点其中的问题,谢谢!!有时间会继续放出 MVC 其它核心技术。如 Model 绑定、数据验证等,同时认真向 Artech 学习!!!!
[转] 仅此一文让你明白 ASP.NET MVC 原理