博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NetCore MVC中的路由(2)在路由中使用约束
阅读量:5129 次
发布时间:2019-06-13

本文共 4872 字,大约阅读时间需要 16 分钟。

.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匹配成功,id123

Home/Index/abc 匹配失败,因为abc无法转换为int?

Home/Index匹配成功,此时idnull

和配置默认值一样,除了直接在模板中配置外,也可以在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(0)}

这个模板中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(0)            })});

可以达到同样的效果,不过直接写到模板更加简洁和直观。

0x02 .NetCore MVC中内建的约束

.NetCore MVC中内建了大量的约束可供使用。其中大多数基于类型的约束都是使用该类型的TryParse()来尝试转换变量提取出来的字符串,返回ture则通过约束,返回false违反约束。

1.约束为intint,对应的类为IntRouteConstraint

例子:{controller=Home}/{action=Index}/{id:int }”

2.约束为floatfloat,对应的类为FloatRouteConstraint

例子:{controller=Home}/{action=Index}/{id:float }”

3.约束为longlong,对应的类为LongRouteConstraint

例子:{controller=Home}/{action=Index}/{id:long}”

4.约束为doubledouble,对应的类为DoubleRouteConstraint

例子:{controller=Home}/{action=Index}/{id:double }”

5.约束为decimaldecimal,对应的类为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.约束为GUIDguid,对应的类为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 % 2 == 0;    }}

然后这样配置路由来约束id:

routes.MapRoute(    name: "default",    template: "{controller}/{action}/{id?}",    defaults: new    {        controller = "Home",        action = "Index",    },    constraints: new    {        id = new EvenRouteConstraint()});

这样配置后

Path路由到HomeControllerIndexid为空

Home/Index/12路由到HomeControllerIndexid12,是偶数

Home/Index/13匹配失败,id13,不是偶数。

除了使用constraints参数添加自定义路由约束外,也可以把自定义路由约束映射为字符串,用于路由模板中。

public void ConfigureServices(IServiceCollection services){        services.Configure
(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 

 


更多内容欢迎访问我的博客:

转载于:https://www.cnblogs.com/durow/p/6012788.html

你可能感兴趣的文章
绝望的第四周作业
查看>>
一月流水账
查看>>
数论四大定理
查看>>
npm 常用指令
查看>>
C#基础知识面试经典[整理]
查看>>
20几个正则常用正则表达式
查看>>
TextArea中定位光标位置
查看>>
非常棒的Visual Studo调试插件:OzCode 2.0 下载地址
查看>>
判断字符串在字符串中
查看>>
hdu4374One hundred layer (DP+单调队列)
查看>>
类间关系总结
查看>>
properties配置文件读写,追加
查看>>
Linux环境下MySql安装和常见问题的解决
查看>>
lrzsz——一款好用的文件互传工具
查看>>
ZPL语言完成条形码的打印
查看>>
这20件事千万不要对自己做!
查看>>
Linux环境下Redis安装和常见问题的解决
查看>>
Android开发中常见问题分析及解决
查看>>
玩转小程序之文件读写
查看>>
Android开发中UI相关的问题总结
查看>>