原文地址:http://www.cnblogs.com/DotCpp/p/3269043.html

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的代码如下:

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激活里面,相关类关系如下图所示:

同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中,代码如下:

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学习!!!!

最新文章

  1. MySQL主主复制+MMM实现高可用
  2. 用淘宝ip地址库查ip
  3. 多重背包问题:POJ2392
  4. Odoo10尝鲜: 退货
  5. 修改Tomcat编码方式的两种方法
  6. CSS 中浮动的使用
  7. unix 常用命令
  8. PHP批量审核ajax jquery
  9. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.0
  10. Codeforces 700B Connecting Universities(树形DP)
  11. css图片上下垂直居中
  12. HDOJ 2442 -bricks 状态压缩DP 一直TLE.打表过的..
  13. Tabhost中Activity绑定Service
  14. VC++读取图像RGB值
  15. 磁盘管理 lvm减容扩容
  16. python 爬虫爬取内容时, \xa0 、 \u3000 的含义
  17. netty同端口监听tcp和websocket协议
  18. JavaScript中调皮的undefined
  19. Servlet 线程安全
  20. Fedora安装Snapd和Snap软件包

热门文章

  1. flexbox父盒子align-items属性
  2. PowerDesigner导出word,PowerDesigner把表导出到word,PDM导出word文档
  3. AliRedis单机180w QPS, 8台服务器构建1000w QPS Cache集群
  4. javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
  5. vue的首页渲染了两次的原因以及解决方法
  6. Spring Mvc 页面传递数组到后台接收
  7. Yii 开发过程 tips
  8. IOS多线程之序
  9. Androidの解决自动旋转导致activity重启问题
  10. 列式存储hbase系统架构学习