UrlRouting路由流程:

添加路由:可以通过调用MapRoute()、MapPageRoute(),它们内部都是创建Route对象,最终添加到RouteCollection中。

    还可以使用[Route("/home/index")]的方式添加,注册路由时需要执行RouteConfig.RegisterRoutes(RouteTable.Routes);

    或者直接调用RouteCollection.Add()方法注册路由

匹配路由:调用RouteCollection的GetRouteData(),最终调用Route中的GetRouteData(),如果返回非null,则匹配

排除路由:IgnoreRoute(),也是往RouteCollection中添加了一个Route对象,Route中的handler是StopRoutingHandler。在路由配置时,如果匹配到的路由的Handler是StopRoutingHandler,请求中断

说明:

MapRoute()是添加MVC路由,MapPageRoute()是添加WebForm路由。它们的RouteHandler不同,MVC的是MVCRouteHandler,WebForm的是PageRouteHandler

MVCRouteHandler内部可以获取到IHttpHandler,实现类是MVCHander,它的PR方法中创建Controller,并调用Action

PageRouteHandler同上,它的IHttpHandler的实现类是Page,Page中有几个事件,我们可以在事件回调中做操作。

MVC和WebForm都是用的ASP.NET框架,从路由开始有了差别,一个创建Controller,一个创建Page。

自定义Route:

可以自定义做一些限制等操作,比如限制域名

    /// <summary>
/// 支持泛域名的UrlRouting
/// </summary>
public class DomainRoute : RouteBase
{
#region 变量
private string _domainName;
private string _physicalFile;
private string _routeUrl;
private bool _checkPhysicalUrlAccess = false;
private RouteValueDictionary _defaults;
private RouteValueDictionary _constraints;
private IList<PathSegment> _pathSegmentLists = new List<PathSegment>();
private const string REPLACE_PATTEN = @"([\w,%]+)";
private readonly Regex _patten = new Regex(@"\{([a-z,A-Z,0-9]+)\}", RegexOptions.Compiled);
private int _segmentCount = ;
#endregion #region 构造函数
/// <summary>
///
/// </summary>
/// <param name="domainName">泛域名</param>
/// <param name="routeUrl">Url路由</param>
/// <param name="physicalFile">映射的物理文件</param>
/// <param name="checkPhysicalUrlAccess">一个值,该值指示 ASP.NET 是否应验证用户是否有权访问物理 URL(始终会检查路由 URL)。此参数设置 System.Web.Routing.PageRouteHandler.CheckPhysicalUrlAccess</param>
/// <param name="defaults">路由的默认值。</param>
/// <param name="constraints">一些约束,URL 请求必须满足这些约束才能作为此路由处理。</param> public DomainRoute(string domainName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints)
{
this._domainName = domainName.ToLower();
this._routeUrl = routeUrl;
this._physicalFile = physicalFile;
this._checkPhysicalUrlAccess = checkPhysicalUrlAccess;
this._defaults = defaults;
this._constraints = constraints; IList<string> lists = SplitUrlToPathSegmentStrings(routeUrl);
if (lists != null && lists.Count > )
{
this._segmentCount = lists.Count;
for (int i = ; i < lists.Count; i++)
{
string strPatten = lists[i];
if (!string.IsNullOrWhiteSpace(strPatten) && this._patten.IsMatch(strPatten))
{
PathSegment segment = new PathSegment();
segment.Index = i; Match match;
List<string> valueNames = new List<string>();
for (match = this._patten.Match(strPatten); match.Success; match = match.NextMatch())
{
strPatten = strPatten.Replace(match.Groups[].Value, REPLACE_PATTEN);
valueNames.Add(match.Groups[].Value);
}
segment.ValueNames = valueNames.ToArray();
segment.Regex = new Regex(strPatten, RegexOptions.Compiled | RegexOptions.IgnoreCase);
this._pathSegmentLists.Add(segment);
}
}
}
} public DomainRoute(string domainName, string routeUrl, string physicalFile)
: this(domainName, routeUrl, physicalFile, false, new RouteValueDictionary(), new RouteValueDictionary())
{ }
#endregion #region 属性
/// <summary>
/// 泛域名
/// </summary>
public string DomainName
{
get { return this._domainName; }
set { this._domainName = value; }
}
/// <summary>
/// 映射的物理文件
/// </summary>
public string PhysicalFile
{
get { return this._physicalFile; }
set { this._physicalFile = value; }
}
/// <summary>
/// Url路由
/// </summary>
public string RouteUrl
{
get { return this._routeUrl; }
set { this._routeUrl = value; }
}
#endregion #region 方法
[DebuggerStepThrough]
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
HttpRequestBase request = httpContext.Request;
if (request.Url.Host.ToLower().Contains(this._domainName))
{
string virtualPath = request.AppRelativeCurrentExecutionFilePath.Substring() + request.PathInfo;
IList<string> segmentUrl = SplitUrlToPathSegmentStrings(virtualPath);
if (segmentUrl.Count == this._segmentCount)
{
PathSegment pathSegment = null;
string path = null;
bool isOK = true;
for (int i = ; i < this._pathSegmentLists.Count; i++)
{
pathSegment = this._pathSegmentLists[i];
path = segmentUrl[pathSegment.Index];
if (!pathSegment.Regex.IsMatch(path))
{
isOK = false;
break;
}
}
if (isOK)
{
result = new RouteData(this, new PageRouteHandler(this._physicalFile, this._checkPhysicalUrlAccess));
result.Values.Add("Domain", this._domainName);
Match match = null;
for (int i = ; i < this._pathSegmentLists.Count; i++)
{
pathSegment = this._pathSegmentLists[i];
path = segmentUrl[pathSegment.Index];
match = pathSegment.Regex.Match(path);
if (pathSegment.ValueNames.Length + == match.Groups.Count)
{
for (int j = ; j < pathSegment.ValueNames.Length; j++)
{
result.Values.Add(pathSegment.ValueNames[j], match.Groups[j + ].Value);
}
}
}
}
}
segmentUrl.Clear();
segmentUrl = null;
}
return result;
} public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return new VirtualPathData(this, this._physicalFile);
} private static IList<string> SplitUrlToPathSegmentStrings(string url)
{
List<string> list = new List<string>();
if (!string.IsNullOrEmpty(url))
{
int index;
for (int i = ; i < url.Length; i = index + )
{
index = url.IndexOf('/', i);
if (index == -)
{
string str = url.Substring(i);
if (str.Length > )
{
list.Add(str);
}
return list;
}
string item = url.Substring(i, index - i);
if (item.Length > )
{
list.Add(item);
}
//list.Add("/");
}
}
list.TrimExcess();
return list;
}
#endregion #region 内部类
private class PathSegment
{
public int Index { get; set; }
public Regex Regex { get; set; }
public string[] ValueNames { get; set; }
}
#endregion
}

添加路由:

RouteTable.Routes.Add(new DomainRoute(urlRoutingSetting.DomainName, urlRoutingSetting.RouteUrl, urlRoutingSetting.PhysicalFile, urlRoutingSetting.CheckPhysicalUrlAccess, urlRoutingSetting.Defaults, constraints));

UrlRouting原理笔记的更多相关文章

  1. 多线程之CountDownLatch的用法及原理笔记

    前言-CountDownLatch是什么? CountDownLatch是具有synchronized机制的一个工具,目的是让一个或者多个线程等待,直到其他线程的一系列操作完成. CountDownL ...

  2. 磁盘文件I/O,SSD结构,局部性原理 笔记

    磁盘文件I/O过程 进程向内核发起read scene.dat请求: 内核根据inode获取对应该进程的address space,在address space查找page_cache,如果没有找到, ...

  3. Http协议工作特点和工作原理笔记

    工作特点: (1)B/S结构(Browser/Server,浏览器/服务器模式) (2)无状态 (3)简单快速.可使用超文本传输协议.灵活运行传输各种类型 工作原理: 客户端发送请求浏览器 -> ...

  4. vuex原理笔记

    本文总结自: https://tech.meituan.com/vuex-code-analysis.html, 将要点提炼为笔记,以便不时之需,安不忘危. 核心可分为两部分: 1.vue.use(V ...

  5. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  6. 机器学习之主成分分析PCA原理笔记

    1.    相关背景 在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律.多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的 ...

  7. 学习Elasticsearch原理笔记

    Elasticsearch是一个分布式可拓展的实时搜索和分析引擎 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索 实时分析的分布式搜索引擎 可以拓展到上百台服务器,处理PB级别的结构化或 ...

  8. Kafka原理笔记

    1.什么是kafka? Kafka是一种分布式的,基于发布/订阅的消息系统(消息队列). 2.为什么要用kafka? 当业务逻辑变得复杂,数据量也会越来越多.此时可能需要增加多条数据线,每条数据线将收 ...

  9. BootStrap栅格系统原理 笔记

    1.内容居中:效果 关键代码: <div class="container"> .........之前上面添加在body标签下的代码 </div>添加cla ...

随机推荐

  1. 题解 P3693 【琪露诺的冰雪小屋】

    知识点: 模拟 , 信仰 原题面 大 型 车 万 众 自 裁 现 场 分析题意: 操作: ICE_BARRAGE R C D S R:行 , C:列, D:方向 , S:强度 在(R,C) 向 D 射 ...

  2. Flume笔记

    flume自定义拦截器:实现Interceptor接口flume自定义source:继承AbstractSourceflume自定义sink:继承AbstractSink azkaban:任务调度工具 ...

  3. fatal error compiling: tools.jar not found

    在Eclipse中使用Maven提供的Install(打包)命令插件的时候报错[Fatal error compiling: tools.jar not found]. 报错的原因 报错的原因从错误信 ...

  4. postman强大的团队协作功能

    今天无意在调项目的接口 ,使用的postman工具 ,自己写的接口信息,只能自己看 ,感觉有点不方便,如果一个公司多名测试,如果一个人写接口信息,大家都能用,就会很节约时间 所以团队协作的功能就诞生了 ...

  5. 【spring】自定义注解 custom annotation

    自定义注解 custom annotation 使用场景 类属性自动赋值. 验证对象属性完整性. 代替配置文件功能,像spring基于注解的配置. 可以生成文档,像java代码注释中的@see,@pa ...

  6. css3伪类和伪元素你都懂了吗

    什么是伪类? 伪类用于定义元素的特殊状态. 例如,它可用于: 当用户将鼠标悬停在元素上时为其设置样式 访问和未访问的链接不同样式 在获得焦点时设置元素的样式 伪类的语法 后代选择器匹配作为指定元素后代 ...

  7. SharpGL之Viewport

    视口变换主是将视景体内投影的物体显示到二维的视口平面上. 在计算机图形学中,它的定义是将经过几何变换, 投影变换和裁剪变换后的物体显示于屏幕指定区域内. 前面我们讨论过的透视投影, 正射投影, 它们都 ...

  8. android studio学习----gradle命令详解

    首先来给大家介绍一种简便并且个人最喜欢的一种办法.很多时候我们在GitHub上看到一个不错的开源项目,一般有两种需求,阅读源码和查看运行效果,如果是单纯的查看源码我更喜欢用一些轻量级编辑器,如vim, ...

  9. curl tftp libcurl 功能使用

    #include <curl/curl.h> static size_t read_callback(void *ptr, size_t size, size_t nmemb, void ...

  10. 配置全文搜索引擎solr

    前言 solr是apache下的一个子项目,用java编写基于Lucene开发的全文搜索服务器,不同于Lucene,solr一个完成的搜索服务器,提供了众多接口调用,而Lucene只是个工具包.如果用 ...