RouteData

 public class RouteData
{
private RouteValueDictionary _dataTokens;
private IRouteHandler _routeHandler;
private RouteValueDictionary _values;
public RouteData()
{
this._values = new RouteValueDictionary();
this._dataTokens = new RouteValueDictionary();
} public RouteData(RouteBase route, IRouteHandler routeHandler)
{
this._values = new RouteValueDictionary();
this._dataTokens = new RouteValueDictionary();
this.Route = route;
this.RouteHandler = routeHandler;
} public string GetRequiredString(string valueName)
{
object obj2;
if (this.Values.TryGetValue(valueName, out obj2))
{
string str = obj2 as string;
if (!string.IsNullOrEmpty(str))
{
return str;
}
}
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("RouteData_RequiredValue"), new object[] { valueName }));
} public RouteValueDictionary DataTokens
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this._dataTokens;
}
} public RouteBase Route
{
get
{
return this.<Route>k__BackingField;
}
set
{
this.<Route>k__BackingField = value;
}
} public IRouteHandler RouteHandler
{
get
{
return this._routeHandler;
}
set
{
this._routeHandler = value;
}
} public RouteValueDictionary Values
{
get
{
return this._values;
}
}
}

RouteData 封装有关路由的信息的类;属性DataTokens是个字典集合,主要存储传递到路由处理程序但未使用的自定义值的集合。比如说Namespace等;

属性Route表示当前的路由的对象,属性Values表示的是路由的 URL 参数值和默认值的集合。属性RouteHandler是继承IRouteHandler的接口的类,在IRouteHandler接口中的GetHttpHandler方法获取到处理页面请求的IHttpHandler;在MVC中RouteData的对象的RouteHandler一般为MvcRouteHandler或是StopRoutingHandler;

    public interface IRouteHandler
{
IHttpHandler GetHttpHandler(RequestContext requestContext);
}

RouteBase

    public abstract class RouteBase
{
private bool _routeExistingFiles = true;
protected RouteBase()
{
}
// 当在派生类中重写时,会返回有关请求的路由信息。
public abstract RouteData GetRouteData(HttpContextBase httpContext);
//当在派生类中重写时,会检查路由是否与指定值匹配,如果匹配,则生成一个 URL,然后检索有关该路由的信息
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); public bool RouteExistingFiles// 如果 ASP.NET 路由操作处理所有请求(甚至包括与现有文件匹配的请求),则为 true;否则为 false。 默认值为 false。
{
get
{
return this._routeExistingFiles;
}
set
{
this._routeExistingFiles = value;
}
}
}
RouteBase 为Route的抽象基类,有2个抽象方法GetRouteData获取当前的RouteData ,GetVirtualPath方法获取相关的虚拟url;

Route

Route类提供用于定义路由及获取路由相关信息的属性和方法,Route类继承了RouteBase 类,并重写了RouteBase 中的GetRouteData方法和GetVirtualPath方法;

public class Route : RouteBase
{
private ParsedRoute _parsedRoute;
private string _url;
private const string HttpMethodParameterName = "httpMethod";
public Route(string url, IRouteHandler routeHandler)
{
this.Url = url;
this.RouteHandler = routeHandler;
}
public Route(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
{
this.Url = url;
this.Defaults = defaults;
this.RouteHandler = routeHandler;
} public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
{
this.Url = url;
this.Defaults = defaults;
this.Constraints = constraints;
this.RouteHandler = routeHandler;
} public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
{
this.Url = url;
this.Defaults = defaults;
this.Constraints = constraints;
this.DataTokens = dataTokens;
this.RouteHandler = routeHandler;
} public override RouteData GetRouteData(HttpContextBase httpContext)
{
string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring() + httpContext.Request.PathInfo;
RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults);
if (values == null)
{
return null;
}
RouteData data = new RouteData(this, this.RouteHandler);
if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
{
return null;
}
foreach (KeyValuePair<string, object> pair in values)
{
data.Values.Add(pair.Key, pair.Value);
}
if (this.DataTokens != null)
{
foreach (KeyValuePair<string, object> pair2 in this.DataTokens)
{
data.DataTokens[pair2.Key] = pair2.Value;
}
}
return data;
} public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
BoundUrl url = this._parsedRoute.Bind(requestContext.RouteData.Values, values, this.Defaults, this.Constraints);
if (url == null)
{
return null;
}
if (!this.ProcessConstraints(requestContext.HttpContext, url.Values, RouteDirection.UrlGeneration))
{
return null;
}
VirtualPathData data = new VirtualPathData(this, url.Url);
if (this.DataTokens != null)
{
foreach (KeyValuePair<string, object> pair in this.DataTokens)
{
data.DataTokens[pair.Key] = pair.Value;
}
}
return data;
}
protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
object obj2;
IRouteConstraint constraint2 = constraint as IRouteConstraint;
if (constraint2 != null)
{
return constraint2.Match(httpContext, this, parameterName, values, routeDirection);
}
string str = constraint as string;
if (str == null)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_ValidationMustBeStringOrCustomConstraint"), new object[] { parameterName, this.Url }));
}
values.TryGetValue(parameterName, out obj2);
string input = Convert.ToString(obj2, CultureInfo.InvariantCulture);
string pattern = "^(" + str + ")$";
return Regex.IsMatch(input, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
} private bool ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection)
{
if (this.Constraints != null)
{
foreach (KeyValuePair<string, object> pair in this.Constraints)
{
if (!this.ProcessConstraint(httpContext, pair.Value, pair.Key, values, routeDirection))
{
return false;
}
}
}
return true;
} public RouteValueDictionary Constraints
{
get
{
return this.<Constraints>k__BackingField;
}
set
{
this.<Constraints>k__BackingField = value;
}
} public RouteValueDictionary DataTokens
{ get
{
return this.<DataTokens>k__BackingField;
}
set
{
this.<DataTokens>k__BackingField = value;
}
} public RouteValueDictionary Defaults
{ get
{
return this.<Defaults>k__BackingField;
}
set
{
this.<Defaults>k__BackingField = value;
}
} public IRouteHandler RouteHandler
{ get
{
return this.<RouteHandler>k__BackingField;
}
set
{
this.<RouteHandler>k__BackingField = value;
}
} public string Url
{
get
{
return (this._url ?? string.Empty);
}
set
{
this._parsedRoute = RouteParser.Parse(value);
this._url = value;
}
}
}

在我们调用的   routes.MapRoute方法时Route对象被创建;

属性Url:获取或设置路由的 URL 模式。
属性Constraints:取或设置为 URL 参数指定有效值的表达式的词典。添加到Constraints字典中的数据,必须是字符串或是满足IRouteConstraint接口的类;

属性DataTokens: 获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值。比如Namespace,Area等数据;对应于RouteData中的DataTokens;

属性 Defaults:获取或设置要在 URL 不包含所有参数时使用的值,

属性 RouteHandler:对应于RouteData中的RouteHandler;

关于 Route中的GetRouteData方法的执行过程可以参考dz45693写的asp.net mvc源码分析-Route的GetRouteData

RouteCollection

RouteCollection类是存储route的集合,在RouteCollection中存在GetRouteData方法时获取匹配当前的路由;

public class RouteCollection : Collection<RouteBase>
{
............. public RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
if (httpContext.Request == null)
{
throw new ArgumentException(System.Web.SR.GetString("RouteTable_ContextMissingRequest"), "httpContext");
}
if (base.Count != )
{
bool flag = false;
bool flag2 = false;
if (!this.RouteExistingFiles)
{
flag = this.IsRouteToExistingFile(httpContext);
flag2 = true;
if (flag)
{
return null;
}
}
using (this.GetReadLock())
{
foreach (RouteBase base2 in this)
{
RouteData routeData = base2.GetRouteData(httpContext);
if (routeData != null)
{
if (!base2.RouteExistingFiles)
{
if (!flag2)
{
flag = this.IsRouteToExistingFile(httpContext);
flag2 = true;
}
if (flag)
{
return null;
}
}
return routeData;
}
}
}
}
return null;
} ..............
}

在RouteCollection.GetRouteData方法时,会循环变量当前的RouteCollection中的Route集合,如果能找到匹配的RouteData的话,直接返回,终止循环,从这里可以看出在定义Route的顺序很重要,尽量特殊的匹配

规则写在前面;

RouteTable

RouteTable类很简单,就是包含一个RouteCollection类

     public class RouteTable
{
private static RouteCollection _instance = new RouteCollection(); public static RouteCollection Routes
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return _instance;
}
}
}

ASP.NET MVC 路由系统类的更多相关文章

  1. asp.net MVC 路由系统

    ASP.NET的路由系统是基于物理文件的路由注册,通过调用System.Routing.RouteTable的Routes(RouteCollection)属性的MapPageRoute()方法来完成 ...

  2. asp.net Mvc 路由详解,非常详细.

    关于路由的理解 为什么要定义路由?路由的定义在开发中的工作量非常小,但是非常重要,因为任何请求都离不开路由. 各个电商网站的 URL 使用非常灵活,都离不开路由的定义,请大家参考几家电商的 URL 如 ...

  3. ASP.NET MVC , ASP.NET Web API 的路由系统与 ASP.NET 的路由系统是怎么衔接的?

      ASP.NET MVC 的路由实际上是建立在 ASP.NET 的路由系统之上的. MVC 路由注册通常是这样的: RouteTable 是一个全局路由表, 它的 Routes 静态属性是一个 Ro ...

  4. ASP.NET MVC 路由(二)

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

  5. ASP.NET MVC 路由(三)

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

  6. ASP.NET MVC 路由(四)

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

  7. ASP.NET MVC路由

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

  8. asp.net MVC 路由机制

    1:ASP.NET的路由机制主要有两种用途: -->1:匹配请求的Url,将这些请求映射到控制器 -->2:选择一个匹配的路由,构造出一个Url 2:ASP.NET路由机制与URL重写的区 ...

  9. asp.net MVC 路由机制 Route

    1:ASP.NET的路由机制主要有两种用途: -->1:匹配请求的Url,将这些请求映射到控制器 -->2:选择一个匹配的路由,构造出一个Url 2:ASP.NET路由机制与URL重写的区 ...

随机推荐

  1. Jenkins--持续集成服务器

    1.持续集成: 1.1概念 持续集成,Continuous integration ,简称CI. 集成:我们所有项目的代码都是托管在SVN服务器上.每个项目都要有若干个单元测试,并有一个所谓集成测试. ...

  2. obj比较

    <script> var obj1={name:'one',age:30}; var obj2={name:'one',age:30}; //比较两个字符串对象的[值]是否相等 Objec ...

  3. SSH整合不错的博客

    https://blog.csdn.net/struggling_rong/article/details/63153833?locationNum=9&fps=1  好好看看看哦

  4. SpringMVC整合ActiveMQ

    spring activeMq 配置 <!-- ActiveMQ 连接工厂 --> <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服 ...

  5. JS与JAVA数据类型的区别

    JavaScript与Java数据类型的区别   阅读目录 Number String Boolean Null Undefined Object 今天开始正式认真学习js,虽然在平常j2ee开发中也 ...

  6. Django学习笔记之django-debug-toolbar使用指南

    介绍 django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息. github地址 文档地址 安装 pip3 in ...

  7. Django框架搭建(windows系统)

    Django框架搭建(windows系统) 一.Django简介 开放源代码的Web应用框架,由Python语言编写,一个大而全的框架. 1.web框架介绍 具体介绍Django之前,必须先介绍WEB ...

  8. 20135320赵瀚青LINUX第五周学习笔记

    赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 按照刘老师的周从三个角 ...

  9. Java搞笑注释(佛-)

    // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\____ // . ' \\| ...

  10. vscode调试pomelo和pomelo使用vscode调试

    使用vscode 通过端口remote attach进行调试 pomelo. 0. 网上好多调试pomelo的都是webstorm.或者vscode调试node的教程.但没找到vscode调试pome ...