首先我们通过在Global.asax中的Application_Start将路由信息注册到RouteTable的Routes静态属性中。如下代码所示:

public class RouteTable
{
//省略
public static RouteCollection Routes { get; }
} protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
} 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 }
);
}
//MapRoute有多个重载,最终实例如下
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
{
  //省略
Route route = new Route(url, new MvcRouteHandler())
{
Defaults = CreateRouteValueDictionaryUncached(defaults),
Constraints = CreateRouteValueDictionaryUncached(constraints),
DataTokens = new RouteValueDictionary()
}; ConstraintValidation.Validate(route); if ((namespaces != null) && (namespaces.Length > ))
{
route.DataTokens[RouteDataTokenKeys.Namespaces] = namespaces;
} routes.Add(name, route); return route;
}

在new Route对象的同时,我们同时new了一个MvcRouteHandler对象实例传进去。然后将route添加到RouteTable的静态属性RouteCollection中,同时返回该route实例。路由注册完毕。

MVC通过在IHttpModule的实现类UrlRoutingModule的Init方法中拦截HttpApplication的PostResolveRequestCache事件来处理请求。代码如下:

public class UrlRoutingModule : IHttpModule
{
public RouteCollection RouteCollection
{
get
{
if (this._routeCollection == null)
{
this._routeCollection = RouteTable.Routes;
}
return this._routeCollection;
}
set
{
this._routeCollection = value;
}
}
protected virtual void Init(HttpApplication application)
{
//省略
application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
} private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
HttpApplication httpApplication = (HttpApplication)sender;
HttpContextBase context = new HttpContextWrapper(httpApplication.Context);
this.PostResolveRequestCache(context);
} public virtual void PostResolveRequestCache(HttpContextBase context)
{
RouteData routeData = this.RouteCollection.GetRouteData(context);
//省略
IRouteHandler routeHandler = routeData.RouteHandler;
//省略
RequestContext requestContext = new RequestContext(context, routeData);
context.Request.RequestContext = requestContext;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
//省略
if (!(httpHandler is UrlAuthFailureHandler))
{
context.RemapHandler(httpHandler);
return;
}
//省略
}
}

插一句,UrlRoutingModule中的RouteCollection默认来自对RouteTable的静态属性Routes的引用。

拦截之后,通过RouteCollection的GetRouteData获得相应的路由数据RouteData的实例routeData。routeData有一个属性RouteHandler,在注册路由时,实例化Route时,我们实例化了一个MvcRouteHandler给构造函数,这里RouteHandler属性其实MvcRouteHandler的实例引用(如下代码片段中的Route)。

然后我们routeHandler是的GetHttpHandler方法,获取到IHttpHandler(如下代码片段中的MvcRouteHandler 类)。

//代码片段三
public class Route : RouteBase
{
//省略
public IRouteHandler RouteHandler
{
get;
set;
} public string Url
{
get
{
return this._url ?? string.Empty;
}
set
{
this._parsedRoute = RouteParser.Parse(value);
this._url = value;
}
} public Route(string url, IRouteHandler routeHandler)
{
this.Url = url;
this.RouteHandler = routeHandler;
} public override RouteData GetRouteData(HttpContextBase httpContext)
{
string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring() + httpContext.Request.PathInfo;
RouteValueDictionary routeValueDictionary = this._parsedRoute.Match(virtualPath, this.Defaults);
if (routeValueDictionary == null)
{
return null;
}
RouteData routeData = new RouteData(this, this.RouteHandler);
if (!this.ProcessConstraints(httpContext, routeValueDictionary, RouteDirection.IncomingRequest))
{
return null;
}
foreach (KeyValuePair<string, object> current in routeValueDictionary)
{
routeData.Values.Add(current.Key, current.Value);
}
if (this.DataTokens != null)
{
foreach (KeyValuePair<string, object> current2 in this.DataTokens)
{
routeData.DataTokens[current2.Key] = current2.Value;
}
}
return routeData;
}
//省略
}
public class MvcRouteHandler : IRouteHandler
{
//省略
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
return new MvcHandler(requestContext);
}
//省略
}

简说mvc路由的更多相关文章

  1. ASP.NET MVC 路由(一)

    ASP.NET MVC路由(一) 前言 从这一章开始,我们即将进入MVC的世界,在学习MVC的过程中在网上搜索了一下,资料还是蛮多的,只不过对于我这样的初学者来看还是有点难度,自己就想看到有一篇引导性 ...

  2. ASP.NET MVC 路由(二)

     ASP.NET MVC路由(二) 前言 在上一篇中,提及了Route.RouteCollection对象的一些信息,以及它们的结构所对应的关系.按照处理流程走下来还有遗留的疑问没有解决这个篇幅就来讲 ...

  3. ASP.NET MVC 路由(三)

    ASP.NET MVC路由(三) 前言 通过前两篇的学习会对路由系统会有一个初步的了解,并且对路由系统中的Url规则有个简单的了解,在大家的脑海中也有个印象了,那么路由系统在ASP.NETMVC中所处 ...

  4. ASP.NET MVC 路由(四)

    ASP.NET MVC路由(四) 前言 在前面的篇幅中我们讲解路由系统在MVC中的运行过程以及粗略的原理,想必看过前面篇幅的朋友应该对路由有个概念性的了解了,本篇来讲解区域,在读完本篇后不会肯定的让你 ...

  5. ASP.NET MVC 路由(五)

    ASP.NET MVC 路由(五) 前言 前面的篇幅讲解了MVC中的路由系统,只是大概的一个实现流程,让大家更清晰路由系统在MVC中所做的以及所在的位置,通过模糊的概念描述.思维导图没法让您看到路由的 ...

  6. MVC路由探寻,涉及路由的惯例、自定义片段变量、约束、生成链接和URL等

    引子 在了解MVC路由之前,必须了解的概念是"片段".片段是指除主机名和查询字符串以外的.以"/"分隔的各个部分.比如,在http://site.com/Hom ...

  7. Asp.Net MVC 路由 - Asp.Net 编程 - 张子阳

    http://cache.baiducontent.com/c?m=9d78d513d98316fa03acd2294d01d6165909c7256b96c4523f8a9c12d522195646 ...

  8. ASP.NET MVC 路由进阶(之二)--自定义路由约束

    3.自定义路由约束 什么叫自定义路由约束呢?假如路由格式为archive/{year}/{month}/{day},其中year,month,day是有约束条件的,必须是数字,而且有一定范围. 这时候 ...

  9. 自定义MVC路由配置

    首先我用MVC4新增一个订单查看的功能 1.创建控制器OrderController namespace MvcApplication3.Controllers { public class Orde ...

随机推荐

  1. XRP共识算法

    目录 共识协议属性 账本历史 信任的验证 共识协议属性 XRP Ledger使用的共识协议不同于之前的任何区块链.该协议称为XRP Ledger共识协议,旨在具有以下重要属性: 使用XRP Ledge ...

  2. 每天一道leetcode203-移除链表的元素

    考试结束,班级平均分只拿到了年级第二,班主任于是问道:大家都知道世界第一高峰珠穆朗玛峰,有人知道世界第二高峰是什么吗?正当班主任要继续发话,只听到角落默默想起来一个声音:”乔戈里峰” 前言 2018. ...

  3. Metronic 对话 chat

    http://keenthemes.com/preview/metronic/theme/admin_1/index.html: jquery让滚动条默认在最底部:$('#content').scro ...

  4. MAVEN的基本配置,以及Hello Word

    MAVEN介绍 Maven是一个项目构建工具,参与项目创建.jar包管理.编译.运行.打包和发布等过程. Maven工具目的是以一种简便方式在多个项目中共享jar包. MAVEN安装和配置 Maven ...

  5. Dapper的简单使用(初学者归纳)

    Dapper的简单使用(初学者归纳) //引用:using System;using System.Collections.Generic;using System.Linq;using System ...

  6. Spring扩展:Spring框架的由来

    一.Spring框架的由来

  7. HDU 2639(01背包第K大)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 http://blog.csdn.net/lulipeng_cpp/article/details/758 ...

  8. 工作经验:mybatis 处理 oracle Long 类型

    前言:mybatis 接收 oracle 中 LONG 类型的,报错:无效的列类型: getCLOB not implemented for class oracle.jdbc.driver.T4CL ...

  9. K:顺序表和链表的比较

     顺序表和链表是线性表的两种基本实现形式(链表还有多种变化形式),对于这两种实现方式,没有一种方法可以称是最好的,他们各自有着各自的特点和优缺点,适用于不同的应用场景.  与顺序表相比,链表较为灵活, ...

  10. K:单例模式中存在的问题

      对于单例模式的实现,无论其是否具有懒加载的功能,我们的目标是有且仅生成一个对象.但是,实际上,对于单例模式的一般实现,都会存在着以下的两个问题: 序列化攻击: 对于枚举方式实现的单例模式,并不存在 ...