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 ...
随机推荐
- Paper | Toward Convolutional Blind Denoising of Real Photographs
目录 故事背景 建模现实噪声 CBDNet 非对称损失 数据库 实验 发表在2019 CVPR. 摘要 While deep convolutional neural networks (CNNs) ...
- Idea Intellij 终生破解版
关于Idea Intellij 2018.3.2 破解问题,之前采用 jetbrains-agent.jar 破解,目前该插件已经失效,为了永久终生破解使用Idea,本篇文章提供JetbrainsI ...
- cURL error 60: SSL certificate problem: unable to get local issuer certificate(转)【亲测】
php5.6以上的版本会出现这种问题 解决办法: [开启拓展] extension=curl extension=openssl [配置证书] 访问https://curl.haxx.se/docs/ ...
- Azure EA (1) 查看国内Azure账单
<Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China 有关Azure EA Portal的详细内容,可以参考我的GitHu ...
- springboot2 中Druid和ibatis(baomidou) 遇到org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.iflytek.pandaai.service.multi.mapper.TanancyMapper
调用mapper中任何方法都会出现类似的错误 org.apache.ibatis.binding.BindingException: Invalid bound statement (not foun ...
- Allure自动化测试报告我是这样用的
关于自动化测试报告: 之前用过testNG自带的测试报告.优化过reportNG的测试报告.extentreport.Zreport(大飞总原创),这些是我之前都用过的,也是在去年雯姐和我说过Allu ...
- python asyncio wait和gather
1. wait, 等待某某执行完成以后才执行下一步 FIRST_COMPLETED = concurrent.futures.FIRST_COMPLETED FIRST_EXCEPTION = con ...
- Docker Hub镜像加速器
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务. 1.配置加速地址 vim /etc/docker/daemo ...
- DVWA-文件包含学习笔记
DVWA-文件包含学习笔记 一.文件包含与漏洞 文件包含: 开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含. 文件包含漏洞: 开发人 ...
- gitea/gogs在push操作时报RPC failed的问题
原文发布于:https://www.chenxublog.com/2019/05/26/gitea-gogs-push-rpc-failed.html 最近川普在搞出口管制,GitHub也更新了相应的 ...