从前面篇章的解析, 其实能看的出来, 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 / 路由注册相关推荐

  1. Spring MVC源码解析——HandlerMapping(处理器映射器)

    Sping MVC 源码解析--HandlerMapping处理器映射器 1. 什么是HandlerMapping 2. HandlerMapping 2.1 HandlerMapping初始化 2. ...

  2. 注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ ...

  3. MyBatis3源码解析(7)TypeHandler注册与获取

    简介 在上篇文章中,我们介绍了TypeHandler的简单使用和解析了TypeHandler的处理核心,这篇文章中我们接着看到TypeHandler是如注册和获取使用的 源码解析 TypeHandle ...

  4. MVC 源码系列之路由(一)

    路由系统 注释:这部分的源码是通过Refector查看UrlRoutingModule的源码编写,这部分的代码没有写到MVC中,却是MVC的入口. 简单的说一下激活路由之前的一些操作.一开始是由MVC ...

  5. ARouter init 源码解析(自动注册的实现)

    概要 使用ARouter,我们只需要在必要的地方加上注解,然后在application中init Arouter就可以直接通过代码进行路由跳转了. 为什么我们可以不用写任何注册的代码,就直接跳转到相关 ...

  6. C#软件授权、注册、加密、解密模块源码解析并制作注册机生成license

    最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制.事出突然,只能在现场开发(离开现场软件就不受我们控了).花了不到两个小时实现了简单的注册机制,稍作整理.         ...

  7. MVC源码解析 - 配置注册 / 动态注册 HttpModule

    本来这一篇, 是要继续 Pipeline 的, 但是在 Pipeline之前, 我看到了InitModules()方法, 所以决定, 在中间穿插一篇进来. 这一篇来讲一下 IHttpModule 的加 ...

  8. Spring MVC源码解析

    Spring Mvc结构解析 上图是Dispatcher Servlet的结构图,从图中可以清楚的看到Dispatcher Servlet的继承链,下面我们将基于Spring4.1.6揭开Spring ...

  9. mybatis源码解析(五) --- typehandler注册和处理的查询结果对象的类型转换

    上一次分析了mapper接口动态代理调用的处理过程,在查询结果后,然后转换的java所对应的类型,这篇文章将对这个类型转换处理详细介绍,在Configuration中TypeHandlerRegist ...

  10. Mybatis3 源码解析系列

    简介 Mybatis作为一个优秀的Java持久化框架,在我们的日常工作中相信都会用到,本次源码解析系列,就开始探索下Mybatis 总结 在MyBatis的学习中,首先通读了<MyBatis3源 ...

最新文章

  1. Dalvik中类的加载
  2. 《代码敲不队》第五次作业:项目需求分析改进与系统设计
  3. jQuery mobile 图标
  4. 【面试题】你知道为什么HashMap是线程不安全的吗?
  5. day07 数据类型间的相互转化及字符编码
  6. 6.Django与Ajax
  7. ROS下获取kinectv2相机的仿照TUM数据集格式的彩色图和深度图
  8. Golang——string字符串常用函数(Contains、join、Index、Repeat、Replace、Split、Trim、Fields)
  9. ibatis和hibernate
  10. Cortex-M3的存储器系统
  11. 判断能否组成三角形(水题)
  12. misc on starcraft----starcraft2
  13. (转)实现AI中LOD优化技术
  14. homestead安装swoole扩展
  15. 钉钉 e应用 mysql_钉钉E应用入门总结
  16. SPSS入门笔记记录
  17. Memcached安全基线
  18. 在osgEarth中添加模型的简单示例
  19. 社交网络中基于张量分解的好友推荐
  20. Linux运行python文件出现以下错误:terminate called after throwing an instance of ‘std::runtime_error‘

热门文章

  1. gitee图床失效后处理
  2. Mac下Vmware Fusion配置虚拟机虚拟网卡并配置CENTOS上网
  3. idea中通过搜索添加maven依赖包
  4. linux shell 多个命令一起执行的几种方法
  5. 修改docker内mysql配置后无法启动解决方法
  6. linux删除指定大小的文件,Linux 脚本删除大于指定大小的文件
  7. centos7 mysql server_centos7 mysqlserver 安装过程
  8. 【渝粤题库】陕西师范大学200261 复变函数 作业(专升本、高起本)
  9. IDEA的第一个java程序
  10. Spring Boot中初始化资源的几种方式