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的名字,通过反射创建控制器对象。
  4. 最后执行控制器。执行的实质其实就是执行ActionInvoker.InvokeAction,即根据请求上下文执行相应的Action。

在自定义的MvcHandler中,代码如下:

string controllerName =this.Requestcontext.RouteData.Controller;

IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();

IController controller = controllerFactory.CreateController(this.RequestContext,controllerName);

controller.Execute(this.RequestContext);

最新文章

  1. ios-获取商店已上线app信息
  2. Ubuntu 14.04 升级gcc 4.8到gcc 5.x
  3. 卸载了mysql之后,mysql服务仍在,显示读取描述失败,错误代码2
  4. Perl模块的安装方法
  5. APT攻击将向云计算平台聚焦
  6. 检测一个DOM对象是否为空
  7. HDU 1708
  8. Cloud Computing Deployment Models
  9. Linux设备总线
  10. js常识
  11. 我的WCF之旅(3):在WCF中实现双工通信
  12. 用原生JavaScript实现图片瀑布流的浏览效果
  13. 用chrome按F12抓包 页面跳转POST一瞬间就闪没了
  14. 20140613_JavaWeb学习之开发环境配置篇
  15. Android学习之Drawable(一)
  16. box2d中的物理世界
  17. 图解WebGL&Three.js工作原理
  18. python中没有字符(char)这一基本数据类型
  19. [Swift]LeetCode709. 转换成小写字母 | To Lower Case
  20. PHP 科学计数 转 Double

热门文章

  1. ORACLE用SYS登录报ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER解决方法
  2. 如何将消息发送给Whatsapp联系人
  3. C++的那些事:你真的了解引用吗
  4. UVA - 10891 Game of Sum 区间DP
  5. JS如何实现点击页面内任意的链接均加参数跳转?
  6. Hark的数据结构与算法练习之圈排序
  7. "回复 集赞" 抢 《Apple Watch 苹果开发教程》活动开始了!!!
  8. 如何选中一个Checkbox,设置无效?
  9. 【NOIP2003】传染病控制(-贪心/dfs)
  10. CSS浏览器兼容的那些事儿