MVC源码解析 - UrlRoutingModule / 路由注册
从前面篇章的解析, 其实能看的出来, IHttpModule 可以注册很多个, 而且可以从web.config注册, 可以动态注册. 但是有一个关键性的Module没有讲, 这里就先来讲一下这个关键性的Module -- UrlRoutingModule
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")] public class UrlRoutingModule : IHttpModule {// Fieldsprivate static readonly object _contextKey;private static readonly object _requestDataKey;private RouteCollection _routeCollection;// Methodsstatic UrlRoutingModule();[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]public UrlRoutingModule();protected virtual void Dispose();protected virtual void Init(HttpApplication application);private void OnApplicationPostResolveRequestCache(object sender, EventArgs e);[Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")]public virtual void PostMapRequestHandler(HttpContextBase context);public virtual void PostResolveRequestCache(HttpContextBase context);[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]void IHttpModule.Dispose();[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]void IHttpModule.Init(HttpApplication application);// Propertiespublic RouteCollection RouteCollection { get; [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] set; } }
来看一下他的Init方法, 注册了什么进去.
protected virtual void Init(HttpApplication application) {if (application.Context.Items[_contextKey] == null){application.Context.Items[_contextKey] = _contextKey;application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);} }
从上一篇的那个事件图上可以看到, 这个是注册在缓存检查结束的事件上. 在看这个注册的方法之前, 还需要讲点别的. 因为在执行这个方法之前, 先执行的 Application_Start方法, 在这个方法中, 我们创建了路由表. 并在路由表中加入了匹配的路由规则.
那先来讲一下路由注册吧.
一、路由注册
路由注册这里, 分为一般理由注册,区域路由注册,api路由注册. 这里只介绍一般路由注册, 其实是一样的, 只是注册的匹配规则不同而已.
在Application_Start方法中, 路由注册就是下面这句话了.
RouteConfig.RegisterRoutes(RouteTable.Routes);
先来看一下, 这个方法的参数.
// 摘要: // 存储应用程序的 URL 路由。 [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")] public class RouteTable {// 摘要: // 初始化 System.Web.Routing.RouteTable 类的新实例。public RouteTable();// 摘要: // 获取从 System.Web.Routing.RouteBase 类派生的对象的集合。//// 返回结果: // 包含集合中的所有路由的对象。public static RouteCollection Routes { get; } }
从这里能看到, 其实他传的是一个静态路由集合, 封装成了一个路由表.
接下来就进入这个方法来看一下.
public static void RegisterRoutes(RouteCollection routes) {routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },constraints: new { controller=@"^\w+$", id=@"^\d+$" } //可以不写, 这里是对名称和参数的约束); }
这里的IgnoreRoute就不看了, 直接看MapRoute方法, 这个方法是存放在静态扩展类中的: RouteCollectionExtensions
里面有很多的重载, 我只看那个参数最多的方法吧.
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {if (routes == null){throw new ArgumentNullException("routes");}if (url == null){throw new ArgumentNullException("url");}Route item = new Route(url, new MvcRouteHandler()) {Defaults = CreateRouteValueDictionary(defaults),Constraints = CreateRouteValueDictionary(constraints),DataTokens = new RouteValueDictionary()};if ((namespaces != null) && (namespaces.Length > 0)){item.DataTokens["Namespaces"] = namespaces;}routes.Add(name, item);return item; }
这里就是解析参数, 并创建路由存入路由集合中, 即存入路由表中.
1. 这里出现了一个 MvcRouteHandler的东东, 名字感觉跟MVC有点关系了, 那进去瞧瞧?
public class MvcRouteHandler : IRouteHandler {// Fieldsprivate IControllerFactory _controllerFactory;// Methodspublic MvcRouteHandler();public MvcRouteHandler(IControllerFactory controllerFactory);protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext);protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext);IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext); }
这个GetHttpHandler里面, 有让人激动的东东哦, 先看一下吧, 不继续讲解了
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) {requestContext.HttpContext.SetSessionStateBehavior(this.GetSessionStateBehavior(requestContext));return new MvcHandler(requestContext); }
2. 这里为啥defaults和 constraints 都存成 CreateRouteValueDictionary 类型呢, 这里暂时只看一下他存放到哪里吧.
private static RouteValueDictionary CreateRouteValueDictionary(object values) {IDictionary<string, object> dictionary = values as IDictionary<string, object>;if (dictionary != null){return new RouteValueDictionary(dictionary);}return new RouteValueDictionary(values); }
public RouteValueDictionary(object values) {this._dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);this.AddValues(values); }
从这里看, defaults, constraints , DataTokens 都是相同的类型.
等后面要用的时候, 再去解析吧.
这一篇算是与MVC挂上钩了, 下一篇就正式进入MVC环节的解析.
目录已同步
转载于:https://www.cnblogs.com/elvinle/p/6276986.html
MVC源码解析 - UrlRoutingModule / 路由注册相关推荐
- Spring MVC源码解析——HandlerMapping(处理器映射器)
Sping MVC 源码解析--HandlerMapping处理器映射器 1. 什么是HandlerMapping 2. HandlerMapping 2.1 HandlerMapping初始化 2. ...
- 注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ ...
- MyBatis3源码解析(7)TypeHandler注册与获取
简介 在上篇文章中,我们介绍了TypeHandler的简单使用和解析了TypeHandler的处理核心,这篇文章中我们接着看到TypeHandler是如注册和获取使用的 源码解析 TypeHandle ...
- MVC 源码系列之路由(一)
路由系统 注释:这部分的源码是通过Refector查看UrlRoutingModule的源码编写,这部分的代码没有写到MVC中,却是MVC的入口. 简单的说一下激活路由之前的一些操作.一开始是由MVC ...
- ARouter init 源码解析(自动注册的实现)
概要 使用ARouter,我们只需要在必要的地方加上注解,然后在application中init Arouter就可以直接通过代码进行路由跳转了. 为什么我们可以不用写任何注册的代码,就直接跳转到相关 ...
- C#软件授权、注册、加密、解密模块源码解析并制作注册机生成license
最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制.事出突然,只能在现场开发(离开现场软件就不受我们控了).花了不到两个小时实现了简单的注册机制,稍作整理. ...
- MVC源码解析 - 配置注册 / 动态注册 HttpModule
本来这一篇, 是要继续 Pipeline 的, 但是在 Pipeline之前, 我看到了InitModules()方法, 所以决定, 在中间穿插一篇进来. 这一篇来讲一下 IHttpModule 的加 ...
- Spring MVC源码解析
Spring Mvc结构解析 上图是Dispatcher Servlet的结构图,从图中可以清楚的看到Dispatcher Servlet的继承链,下面我们将基于Spring4.1.6揭开Spring ...
- mybatis源码解析(五) --- typehandler注册和处理的查询结果对象的类型转换
上一次分析了mapper接口动态代理调用的处理过程,在查询结果后,然后转换的java所对应的类型,这篇文章将对这个类型转换处理详细介绍,在Configuration中TypeHandlerRegist ...
- Mybatis3 源码解析系列
简介 Mybatis作为一个优秀的Java持久化框架,在我们的日常工作中相信都会用到,本次源码解析系列,就开始探索下Mybatis 总结 在MyBatis的学习中,首先通读了<MyBatis3源 ...
最新文章
- Dalvik中类的加载
- 《代码敲不队》第五次作业:项目需求分析改进与系统设计
- jQuery mobile 图标
- 【面试题】你知道为什么HashMap是线程不安全的吗?
- day07 数据类型间的相互转化及字符编码
- 6.Django与Ajax
- ROS下获取kinectv2相机的仿照TUM数据集格式的彩色图和深度图
- Golang——string字符串常用函数(Contains、join、Index、Repeat、Replace、Split、Trim、Fields)
- ibatis和hibernate
- Cortex-M3的存储器系统
- 判断能否组成三角形(水题)
- misc on starcraft----starcraft2
- (转)实现AI中LOD优化技术
- homestead安装swoole扩展
- 钉钉 e应用 mysql_钉钉E应用入门总结
- SPSS入门笔记记录
- Memcached安全基线
- 在osgEarth中添加模型的简单示例
- 社交网络中基于张量分解的好友推荐
- Linux运行python文件出现以下错误:terminate called after throwing an instance of ‘std::runtime_error‘