UrlRouting原理笔记
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原理笔记的更多相关文章
- 多线程之CountDownLatch的用法及原理笔记
前言-CountDownLatch是什么? CountDownLatch是具有synchronized机制的一个工具,目的是让一个或者多个线程等待,直到其他线程的一系列操作完成. CountDownL ...
- 磁盘文件I/O,SSD结构,局部性原理 笔记
磁盘文件I/O过程 进程向内核发起read scene.dat请求: 内核根据inode获取对应该进程的address space,在address space查找page_cache,如果没有找到, ...
- Http协议工作特点和工作原理笔记
工作特点: (1)B/S结构(Browser/Server,浏览器/服务器模式) (2)无状态 (3)简单快速.可使用超文本传输协议.灵活运行传输各种类型 工作原理: 客户端发送请求浏览器 -> ...
- vuex原理笔记
本文总结自: https://tech.meituan.com/vuex-code-analysis.html, 将要点提炼为笔记,以便不时之需,安不忘危. 核心可分为两部分: 1.vue.use(V ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
- 机器学习之主成分分析PCA原理笔记
1. 相关背景 在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律.多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的 ...
- 学习Elasticsearch原理笔记
Elasticsearch是一个分布式可拓展的实时搜索和分析引擎 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索 实时分析的分布式搜索引擎 可以拓展到上百台服务器,处理PB级别的结构化或 ...
- Kafka原理笔记
1.什么是kafka? Kafka是一种分布式的,基于发布/订阅的消息系统(消息队列). 2.为什么要用kafka? 当业务逻辑变得复杂,数据量也会越来越多.此时可能需要增加多条数据线,每条数据线将收 ...
- BootStrap栅格系统原理 笔记
1.内容居中:效果 关键代码: <div class="container"> .........之前上面添加在body标签下的代码 </div>添加cla ...
随机推荐
- bolb与base64的图片互转
直接看图简单明了. 注:便于测试你可以自己用base64图片测试互转一下.这里base64图片太长了就不给予展示了,望理解
- Paper | SkipNet: Learning Dynamic Routing in Convolutional Networks
目录 1. 概括 2. 相关工作 3. 方法细节 门限模块的结构 训练方法 4. 总结 作者对residual network进行了改进:加入了gating network,基于上一层的激活值,得到一 ...
- pytest 常见用法
前言 之前一篇文章简单介绍了 pytest 以及 fixture :https://www.cnblogs.com/shenh/p/11572657.html .实际在写自动化测试脚本中,还会有一些很 ...
- Vue.js 源码分析(二十) 指令篇 v-once指令详解
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,例如:<p>Message: {{ msg }}</p>以后每当msg属性发生了改变,插值处的内 ...
- Oracle 查询(SELECT)语句(一)
Ø 简介 本文介绍 Oracle 中查询(SELECT)语句的使用,在 SQL 中 SELECT 语句是相对内容较多的,也是相对比较复杂一点的,所以这里拿出来单独学习. 首先,我们先来理一下思路,我 ...
- Window权限维持(五):屏幕保护程序
屏幕保护是Windows功能的一部分,使用户可以在一段时间不活动后放置屏幕消息或图形动画.众所周知,Windows的此功能被威胁参与者滥用为持久性方法.这是因为屏幕保护程序是具有.scr文件扩展名的可 ...
- kali渗透综合靶机(十)--Raven靶机
kali渗透综合靶机(十)--Raven靶机 一.主机发现 1.netdiscover -i eth0 -r 192.168.10.0/24 二.端口扫描 1. masscan --rate=1000 ...
- SQL server已经设置为单用户模式,Sql server还原失败数据库正在使用,无法获得对数据库的独占访问权
如果已经设置为单用户模式,还是报这个错误的话,就按照一下SQL执行就
- 执行http脚本
Invoke-Expression (Invoke-WebRequest http://10.16.2.5:81/Configcmd.ps1).content
- 解决U盘不能分配空间(windows下操作)
亲测可行 1.WIN+R => cmd => diskpart命令进入工具. 2.使用LIST DISK查看所有磁盘,?提示所有命令. 3.SELECT DISK 1将磁盘聚焦到1号磁盘, ...