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
{
// Fields
private static readonly object _contextKey;
private static readonly object _requestDataKey;
private RouteCollection _routeCollection;
// Methods
static 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);
// Properties
public 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 > ))
{
item.DataTokens["Namespaces"] = namespaces;
}
routes.Add(name, item);
return item;
}
这里就是解析参数, 并创建路由存入路由集合中, 即存入路由表中.
1. 这里出现了一个 MvcRouteHandler的东东, 名字感觉跟MVC有点关系了, 那进去瞧瞧?
public class MvcRouteHandler : IRouteHandler
{
// Fields
private IControllerFactory _controllerFactory; // Methods
public 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环节的解析.
MVC源码解析 - UrlRoutingModule / 路由注册的更多相关文章
- kubernetes源码解析---- apiserver路由构建解析(2)
kubernetes源码解析---- apiserver路由构建解析(2) 上文主要对go-restful这个包进行了简单的介绍,下面我们通过阅读代码来理解apiserver路由的详细构建过程. (k ...
- kubernetes源码解析---- apiserver路由构建解析(1)
kubernetes源码解析---- apiserver路由构建解析(1) apiserver作为k8s集群的唯一入口,内部主要实现了两个功能,一个是请求的路由和处理,简单说就是监听一个端口,把接收到 ...
- MVC源码解析 - 目录
尽管MVC6和MVC4,5已经有很大不同, 但是, 作为一个普通开发人员, 还真没有资格去选择使用哪个版本. So, 尽管已经是old的版本, 还是再次花点时间去温故知新. 我记得在15年初的时候, ...
- MVC 源码系列之路由(一)
路由系统 注释:这部分的源码是通过Refector查看UrlRoutingModule的源码编写,这部分的代码没有写到MVC中,却是MVC的入口. 简单的说一下激活路由之前的一些操作.一开始是由MVC ...
- Spring5源码解析2-register方法注册配置类
接上回已经讲完了this()方法,现在来看register(annotatedClasses);方法. // new AnnotationConfigApplicationContext(AppCon ...
- Mybatis源码解析-MapperRegistry代理注册mapper接口
知识储备 SqlsessionFactory-mybatis持久层操作数据的前提,具体的解析是通过SqlSessionFactoryBean生成的,可见>>>Spring mybat ...
- C#软件授权、注册、加密、解密模块源码解析并制作注册机生成license
最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制.事出突然,只能在现场开发(离开现场软件就不受我们控了).花了不到两个小时实现了简单的注册机制,稍作整理. ...
- MVC源码解析 - 配置注册 / 动态注册 HttpModule
本来这一篇, 是要继续 Pipeline 的, 但是在 Pipeline之前, 我看到了InitModules()方法, 所以决定, 在中间穿插一篇进来. 这一篇来讲一下 IHttpModule 的加 ...
- MVC源码解析 - Http Pipeline 解析(上)
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); 上一篇说到了创建 ...
随机推荐
- Util应用程序框架公共操作类
随笔分类 - Util应用程序框架公共操作类 Util应用程序框架公共操作类 Util应用程序框架公共操作类(五):异常公共操作类 摘要: 任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务 ...
- 浅谈我对几个Web前端开发框架的比较
强调一下,这篇日志主要还是针对想学前端开发的新朋友写的,不是说我有什么独特见解,而是比较客观的状态,就各种框架的异同和应用场合,需要注意的地方做简单描述,不做具体深入分析,有的地方比较抽象,对于抽象之 ...
- 【SSRS】入门篇(一) -- 创建SSRS项目
原文:[SSRS]入门篇(一) -- 创建SSRS项目 在本篇中,您将学习如何在 SQL Server Data Tools (SSDT) 中创建报表服务器项目. 报表服务器项目用于创建在报表服务器中 ...
- easyui datagrid 前台分页
核心方法 //分页data function pagerFilter(data, pagegrid) { if (typeof data.length == 'number' && t ...
- 【工作笔记五】html5的placeholder属性(IE如何兼容placeholder属性)
placeholder属性,IE对其的支持表示无奈,firefox.google chrome表示毫无压力. HTML5对Web Form做了许多增强,比如input新增的type类型.Form Va ...
- C# dll 事件执行 js 回调函数
C# dll 事件执行 js 回调函数 前言: 由于js 远程请求 XMLHttpRequest() 不支持多线程,所以用C# 写了个dll 多线程远程抓住供js调用. 最初代码为: C#代 ...
- Javascript技巧实例精选(5)—显示当前的日期和时间
用Javascript实现在屏幕中打印当前的日期和时间 >>点击这里下载完整html源码<< 这是显示的效果 目前的日期/时间是:Wed Sep 25 2013 23:40:0 ...
- 刚下载的几个开源的Android项目
Android-Universal-Image-Loader Android上最让人头疼的莫过于从网络获取图片.显示.回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你. Universa ...
- xmlDom
加载并解析xml文件: <script type="text/javascript"> try //Internet Explorer { xmlDoc=new Act ...
- FineUI Grid 缓存列显示隐藏状态
当列表字段过多时,需要隐藏掉一些,但是再次打开页面又显示出来了,FineUI没有提供缓存功能,那么自己动手,打开[ext-part2.js]找到 “if (Ext.grid.column.RowNum ...