ASP.NET MVC 路由系统类
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 路由系统类的更多相关文章
- asp.net MVC 路由系统
ASP.NET的路由系统是基于物理文件的路由注册,通过调用System.Routing.RouteTable的Routes(RouteCollection)属性的MapPageRoute()方法来完成 ...
- asp.net Mvc 路由详解,非常详细.
关于路由的理解 为什么要定义路由?路由的定义在开发中的工作量非常小,但是非常重要,因为任何请求都离不开路由. 各个电商网站的 URL 使用非常灵活,都离不开路由的定义,请大家参考几家电商的 URL 如 ...
- ASP.NET MVC , ASP.NET Web API 的路由系统与 ASP.NET 的路由系统是怎么衔接的?
ASP.NET MVC 的路由实际上是建立在 ASP.NET 的路由系统之上的. MVC 路由注册通常是这样的: RouteTable 是一个全局路由表, 它的 Routes 静态属性是一个 Ro ...
- ASP.NET MVC 路由(二)
ASP.NET MVC路由(二) 前言 在上一篇中,提及了Route.RouteCollection对象的一些信息,以及它们的结构所对应的关系.按照处理流程走下来还有遗留的疑问没有解决这个篇幅就来讲 ...
- ASP.NET MVC 路由(三)
ASP.NET MVC路由(三) 前言 通过前两篇的学习会对路由系统会有一个初步的了解,并且对路由系统中的Url规则有个简单的了解,在大家的脑海中也有个印象了,那么路由系统在ASP.NETMVC中所处 ...
- ASP.NET MVC 路由(四)
ASP.NET MVC路由(四) 前言 在前面的篇幅中我们讲解路由系统在MVC中的运行过程以及粗略的原理,想必看过前面篇幅的朋友应该对路由有个概念性的了解了,本篇来讲解区域,在读完本篇后不会肯定的让你 ...
- ASP.NET MVC路由
ASP.NET MVC路由(四) 前言 在前面的篇幅中我们讲解路由系统在MVC中的运行过程以及粗略的原理,想必看过前面篇幅的朋友应该对路由有个概念性的了解了,本篇来讲解区域,在读完本篇后不会肯定的让你 ...
- asp.net MVC 路由机制
1:ASP.NET的路由机制主要有两种用途: -->1:匹配请求的Url,将这些请求映射到控制器 -->2:选择一个匹配的路由,构造出一个Url 2:ASP.NET路由机制与URL重写的区 ...
- asp.net MVC 路由机制 Route
1:ASP.NET的路由机制主要有两种用途: -->1:匹配请求的Url,将这些请求映射到控制器 -->2:选择一个匹配的路由,构造出一个Url 2:ASP.NET路由机制与URL重写的区 ...
随机推荐
- CCF 炉石传说(模拟)
试题编号: 201612-3 试题名称: 炉石传说 时间限制: 1.0s 内存限制: 256.0MB 问题描述 <炉石传说:魔兽英雄传>(Hearthstone: Heroes of Wa ...
- 使用 vim + ctags + cscope + taglist 阅读源码
转自:http://my.oschina.net/u/554995/blog/59927 最近,准备跟学长一起往 linux kernel 的门里瞧瞧里面的世界,虽然我们知道门就在那,但我们还得找到合 ...
- 基于Python操作redis介绍
(注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正.) 毕业前的最后一个学期(2016.03),龙哥结婚了.可是总有些人喜欢嘲笑别人,调侃我.当时我就理直气壮的告诉他们,等龙哥孩子 ...
- Spring Boot+BootStrap fileInput 多图片上传
一.依赖文件 <link rel="stylesheet" type="text/css" th:href="@{/js/bootstrap/c ...
- 20145302张薇《Java程序设计》实验四报告
20145325张薇 实验四:Andoid开发基础 实验内容 使用 Android Studio 设计"Hello" 设计过程 首先创建项目 选择.xml中的`Design 选中W ...
- 20145230熊佳炜《网络对抗》实验九:web安全基础实践
20145230熊佳炜<网络对抗>实验九:web安全基础实践 webgoat webgoat的中文是代罪羔羊的意思,而它是一个有很多漏洞的web应用程序,我们可以利用它来研究关于web应用 ...
- SublimeText3 编辑器使用小结
1. 快捷键: Command + shift + D : 复制当前行 Command + shift + K : 删除当前行 Command + J : 合并一行 Command + Enter : ...
- Vue.js项目部署在Tomcat服务器上
1.在本地的Vue框架中 执行npm run build 将我们的项目打包到dist 文件夹中 2.在服务器上的Tomcat的 webapps文件夹下,新建一个文件夹如:frontvue 3.启动t ...
- LeetCode——Find All Duplicates in an Array
Question Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice an ...
- AD 域中给AD 用加登录本地计算的权限
说明:一般新添加的AD 用户没有登录计算机电脑的权限,如果需要添加登录权限. 步骤:1.打开Active Directory 用户和计算机 步骤:2.打开某个用户 步骤3; 如下图.