.NetCore MVC中的路由(2)在路由中使用约束
.NetCore MVC中的路由(2)在路由中使用约束
0x00
路由模板中的约束
在配置路由模板时,除了以静态字符和变量的形式外,还可以通过配置对变量进行约束。实际如果不嫌麻烦的话在路由到的Action中对变量进行检查也是一种方法,不过对于变量的通用的约束当然是放在路由层面更加合适。而且这样做会简化Action的代码,使Action更加专注于自身业务,符合AOP的思路。这篇文章主要介绍路由模板中的约束。
0x01
在路由模板中使用约束
在路由模板中使用约束是很简单的,如下所示:
{controller=Home}/{action=Index}/{id:int?}
这个模板就对id进行了约束,约束是通过冒号(:)实现的,冒号后为约束的内容。Int?代表id约束为int?类型,只有id能被转换为int?类型模板匹配才算成功。即使用int.TryParse()方法返回true。
Home/Index/123匹配成功,id为123
Home/Index/abc 匹配失败,因为abc无法转换为int?
Home/Index匹配成功,此时id为null
和配置默认值一样,除了直接在模板中配置外,也可以在MapRoute方法中通过传入参数进行配置:
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new
{
controller = "Home",
action = "Index",
},
constraints: new
{
id = new IntRouteConstraint()
});
效果是一样的。
如果我们要对一个变量使用多个约束,只需要在约束后面继续用冒号加约束即可。例如
{controller=Home}/{action=Index}/{id:int:min()}
这个模板中id被约束为int类型且最小值为0。同样的也可以以参数的方式配置:
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new
{
controller = "Home",
action = "Index",
},
constraints: new
{
id = new CompositeRouteConstraint(
new IRouteConstraint[]
{
new IntRouteConstraint(),
new MinRouteConstraint()
})
});
可以达到同样的效果,不过直接写到模板更加简洁和直观。
0x02 .NetCore MVC中内建的约束
.NetCore MVC中内建了大量的约束可供使用。其中大多数基于类型的约束都是使用该类型的TryParse()来尝试转换变量提取出来的字符串,返回ture则通过约束,返回false违反约束。
1.约束为int:int,对应的类为IntRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:int }”
2.约束为float:float,对应的类为FloatRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:float }”
3.约束为long:long,对应的类为LongRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:long}”
4.约束为double:double,对应的类为DoubleRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:double }”
5.约束为decimal:decimal,对应的类为DecimalRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:decimal }”
6.约束为布尔值:bool,对应的类为BoolRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:bool}”
7.约束为字母:alpha,对应的类为AlphaRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:alpha}”
8.约束为时间日期:datetime,对应的类为DateTimeRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:datetime}”
9.约束为GUID:guid,对应的类为GuidRouteConstraint
例子:”{controller=Home}/{action=Index}/{id:bool}”
10.约束长度:length(len),对应的类为LengthRouteConstraint(len)
例子:”{controller=Home}/{action=Index}/{id:length(5)
}”
11.约束最小长度:minlength(len),对应的类为MinLengthRouteConstraint(len)
例子:”{controller=Home}/{action=Index}/{id:minlength(5)}”
12.约束最大长度:maxlength(len),对应的类为MaxLengthRouteConstraint(len)
例子:”{controller=Home}/{action=Index}/{id:maxlength(10)}”
13.约束长度范围:length(min,max),对应的类为LengthRouteConstraint(min,max)
例子:”{controller=Home}/{action=Index}/{id:length(5,10)}”
14.约束最小值:min(v),对应的类为MinRouteConstraint(v)
例子:”{controller=Home}/{action=Index}/{id:min(0)}”
15.约束最大值:max(v),对应的类为MaxRouteConstraint(v)
例子:”{controller=Home}/{action=Index}/{id:max(1000)}”
16.约束范围:range(min,max),对应的类为RangeRouteConstraint(min,max)
例子:”{controller=Home}/{action=Index}/{id:range(0,1000)
}”
17.约束正则表达式:regex(exp),对应的类为RegexRouteConstraint(exp)
例子:”{controller:regex(^My.*)=Home
}/{action=Index}/{id?}”
0x03
创建自定义约束
除了使用内建的约束外,还可以自定义约束。只要实现IRouteConstraint接口即可。这个接口定义了一个方法:
bool Match(
HttpContext httpContext, //Http上下文信息
IRouter route, //当前正在测试的模板信息
string routeKey, //当前正在测试约束的变量名称
RouteValueDictionary values, //模板中变量提取出的值
RouteDirection routeDirection) //路由方向,枚举,值包括IncominRequestg和UrlGeneration
这个方法返回ture说明符合约束,返回false说明违反约束。下面我们通过实现这个接口定义一个约束,把id约束为偶数。
public class EvenRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
int id;
if (!int.TryParse(values[routeKey].ToString(), out id))
return false; return id % == ;
}
}
然后这样配置路由来约束id:
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new
{
controller = "Home",
action = "Index",
},
constraints: new
{
id = new EvenRouteConstraint()
});
这样配置后
空Path路由到HomeController的Index,id为空
Home/Index/12路由到HomeController的Index,id为12,是偶数
Home/Index/13匹配失败,id为13,不是偶数。
除了使用constraints参数添加自定义路由约束外,也可以把自定义路由约束映射为字符串,用于路由模板中。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RouteOptions>(options=>
{
options.ConstraintMap.Add("even",typeof(EvenRouteConstraint));
});
// Add framework services.
services.AddMvc();
}
这样配置后路由模板写成:
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id:even?}");
});
可以达到同样的效果。把约束映射为字符串后,还可以方便的在Route特性中使用,例如:
[Route("durow/Test/[action]/{id:even?}")]
0x04 相关代码
https://github.com/durow/NetCoreStudy/tree/master/src/RouteStudy
更多内容欢迎访问我的博客:http://www.durow.vip
.NetCore MVC中的路由(2)在路由中使用约束的更多相关文章
- .NetCore MVC中的路由(1)路由配置基础
.NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
- MVC路由探寻,涉及路由的惯例、自定义片段变量、约束、生成链接和URL等
引子 在了解MVC路由之前,必须了解的概念是"片段".片段是指除主机名和查询字符串以外的.以"/"分隔的各个部分.比如,在http://site.com/Hom ...
- ASP.NET MVC简单编程之(二)经典路由篇
话题:请求从路由开始 在实际的ASP.NET MVC开发中,URL访问规则----路由的定义是非常重要的.因为任何一个请求都离不开路由.理解它,我们将能理解MVC处理请求的整个过程,灵活地定义系统各种 ...
- ASP.NET MVC学习(一)之路由篇Route
什么是路由 通过[路由]配置,路由可以规定URL的特殊格式,使其达到特殊效果. 在ASP.NET MVC框架中,通过路由配置URL,使用户的URL请求可以映射到Controller下的action方法 ...
- ASP.NET MVC , ASP.NET Web API 的路由系统与 ASP.NET 的路由系统是怎么衔接的?
ASP.NET MVC 的路由实际上是建立在 ASP.NET 的路由系统之上的. MVC 路由注册通常是这样的: RouteTable 是一个全局路由表, 它的 Routes 静态属性是一个 Ro ...
- MVC进阶篇(二)—路由机制
前言 这个东西好像,一般也不经常动,都用默认的即可.由于MVC模式在framework里面的解析机制,区别与webform模式,是采用解析路由机制的url.从来实例化视图列对象,然后对该action进 ...
- asp.netCore3.0 中使用app.UseMvc() 配置路由
一.新配置路由策略 在 Asp.Net Core 3.0中默认不再支持app.UserMvc() 方式配置路由 系统. 而是使用新的模式,点击查看asp.netCore3.0区域和路由配置变化 默认 ...
- ASP.NET MVC 5 入门-2控制器、路由
一.创建项目: 上起始页,选择新项目. 在中新的项目对话框中,右侧语言类别选择C# ,然后项目类型选择Web,然后选择ASP.NET Web 应用程序 (.NET Framework) 项目模板. 将 ...
随机推荐
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- Jquery mobiscroll 移动设备(手机)wap日期时间选择插件以及滑动、滚动插件
Jquery Mobiscroll是一个用于触摸设备(Android phones, iPhone, iPad, Galaxy Tab)的日期和时间选择器jQuery插件.以及各种滑动插件 可以让用户 ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- 关于Raid0,Raid1,Raid5,Raid10的总结
RAID0 定义: RAID 0又称为Stripe或Striping,它代表了所有RAID级别中最高的存储性能.RAID 0提高存储性能的原理是把连续的数据分散到多个磁盘上存取,这样,系统有数据请求就 ...
- [Egret]优雅的写http
首先,自从使用链式调用的写法后,就一发不可收拾的喜爱上了这种优雅的方式.不管是写架构还是写模块,我都会不自觉的使用这种最优雅的方式.链式写法既减少了代码量,又非常优雅的. 在使用 egret 的htt ...
- Unable to create the selected property page. An error occurred while automatically activating bundle net.sourceforge.pmd
解决方案: 在命令行到eclipse目录下使用 eclipse.exe -clean
- BPM配置故事之案例11-操作外部数据源
小明:可以获取ERP数据了-- 老李:哦,这么快?小伙子,我非常看好你,来来,别急着走,再陪我聊会-- 小明:--您老人家不是又要改流程吧? 老李:没有没有,哎嘿嘿嘿,我们这不都是为公司效率着想嘛,这 ...
- 手把手教你做个人 app
我们都知道,开发一个app很大程度依赖服务端:服务端提供接口数据,然后我们展示:另外,开发一个app,还需要美工协助切图.没了接口,没了美工,app似乎只能做成单机版或工具类app,真的是这样的吗?先 ...
- MongoDB学习笔记五—查询上
数据准备 { , "goods_name" : "KD876", "createTime" : ISODate("2016-12- ...
- Linux基础介绍【第二篇】
远程连接Linux的原理 SHH远程连接介绍 当前,在几乎所有的互联网企业环境中,最常用的Linux提供远程连接服务的工具就是SSH软件,SSH分为SSH客户端和SSH服务端两部分.其中,SSH服务端 ...