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. Paper | Toward Convolutional Blind Denoising of Real Photographs

    目录 故事背景 建模现实噪声 CBDNet 非对称损失 数据库 实验 发表在2019 CVPR. 摘要 While deep convolutional neural networks (CNNs) ...

  2. Idea Intellij 终生破解版

    关于Idea Intellij 2018.3.2 破解问题,之前采用 jetbrains-agent.jar  破解,目前该插件已经失效,为了永久终生破解使用Idea,本篇文章提供JetbrainsI ...

  3. cURL error 60: SSL certificate problem: unable to get local issuer certificate(转)【亲测】

    php5.6以上的版本会出现这种问题 解决办法: [开启拓展] extension=curl extension=openssl [配置证书] 访问https://curl.haxx.se/docs/ ...

  4. Azure EA (1) 查看国内Azure账单

    <Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China 有关Azure EA Portal的详细内容,可以参考我的GitHu ...

  5. 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 ...

  6. Allure自动化测试报告我是这样用的

    关于自动化测试报告: 之前用过testNG自带的测试报告.优化过reportNG的测试报告.extentreport.Zreport(大飞总原创),这些是我之前都用过的,也是在去年雯姐和我说过Allu ...

  7. python asyncio wait和gather

    1. wait, 等待某某执行完成以后才执行下一步 FIRST_COMPLETED = concurrent.futures.FIRST_COMPLETED FIRST_EXCEPTION = con ...

  8. Docker Hub镜像加速器

    国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务. 1.配置加速地址 vim /etc/docker/daemo ...

  9. DVWA-文件包含学习笔记

    DVWA-文件包含学习笔记 一.文件包含与漏洞 文件包含: 开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含. 文件包含漏洞: 开发人 ...

  10. gitea/gogs在push操作时报RPC failed的问题

    原文发布于:https://www.chenxublog.com/2019/05/26/gitea-gogs-push-rpc-failed.html 最近川普在搞出口管制,GitHub也更新了相应的 ...