路由约束

ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值、可选和约束。

约束的使用方法是在属性路由上添加指定的约束名,用法如下:

// 单个使用
[Route("users/{id:int}")]
public User GetUserById(int id) { }
// 组合使用
[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

框架内部已经提供了一些约束,如下所示:

约束 示例 匹配项示例 说明
int {id:int} 123456789, -123456789 匹配任何整数
bool {active:bool} true, FALSE 匹配 true或 false(区分大小写)
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm 匹配有效的 DateTime 值(位于固定区域性中 - 查看警告)
decimal {price:decimal} 49.99, -1,000.01 匹配有效的 decimal 值(位于固定区域性中 - 查看警告)
double {weight:double} 1.234, -1,001.01e8 匹配有效的 double 值(位于固定区域性中 - 查看警告)
float {weight:float} 1.234, -1,001.01e8 匹配有效的 float 值(位于固定区域性中 - 查看警告)
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} 匹配有效的 Guid 值
long {ticks:long} 123456789, -123456789 匹配有效的 long 值
minlength(value) {username:minlength(4)} Rick 字符串必须至少为 4 个字符
maxlength(value) {filename:maxlength(8)} Richard 字符串不得超过 8 个字符
length(length) {filename:length(12)} somefile.txt 字符串必须正好为 12 个字符
length(min,max) {filename:length(8,16)} somefile.txt 字符串必须至少为 8 个字符,且不得超过 16 个字符
min(value) {age:min(18)} 19 整数值必须至少为 18
max(value) {age:max(120)} 91 整数值不得超过 120
range(min,max) {age:range(18,120)} 91 整数值必须至少为 18,且不得超过 120
alpha {name:alpha} Rick 字符串必须由一个或多个字母字符(a-z,区分大小写)组成
regex(expression) {ssn:regex(^\d{{3}}-\d{{2}}-\d{{4}}$)} 123-45-6789 字符串必须匹配正则表达式(参见有关定义正则表达式的提示)
required {name:required} Rick 用于强制在 URL 生成过程中存在非参数值

内置的约束能够适用于大部分常见的应用场景,但是有时候我们还是需要去自定义我们想要的效果。

自定义路由约束

自定义约束是要实现IRouteConstraint接口,然后重载Match方法,该方法有四个参数。

第一个参数httpContext是当前请求的上下文

第二个参数route是当前约束所属的路由

第三个参数routeKey是当前检查的变量名,例如文章开头示例中的id

第四个参数values是当前Url匹配的字典值,例如文章开头的示例的路由,如果Url是users/1,那么就有一个字典,其key = idvalue = 1。当然还有其他的变量的值,比如controlleraction等。

第五个参数routeDirection是一个枚举值,代表是web请求的还是用Url.Action等方法生成Url。

举一个实例,我们想要定义一个约束,指定路由传过来的参数必须是指定的枚举值。

我们先定义一个枚举:

public enum BoolEnum
{
True,
False
}

然后定义约束:

public class EnumConstraint : IRouteConstraint
{
private Type _enumType; public EnumConstraint(string enumTypeName)
{
_enumType = Type.GetType(enumTypeName);
} public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
var value = values[routeKey];
if (value == null)
{
return false;
} if (Enum.TryParse(_enumType, value.ToString(), out object result))
{
if (Enum.IsDefined(_enumType, result))
{
return true;
}
} return false;
}
}

Startup.csConfigureServices方法添加自定义约束:

services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("enum", typeof(EnumConstraint));
});

在路由上使用约束:

(WebApplicationTest是当前的namespace)

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
// GET: api/Test
[HttpGet("{bool:enum(" + nameof(WebApplicationTest) + "." + nameof(BoolEnum) + ")}")]
public string Get(BoolEnum @bool)
{
return "bool: " + @bool;
} [HttpGet("{id:int:min(2)}", Name = "Get")]
public string Get(int id)
{
return "id: " + id;
} [HttpGet("{name}")]
public string Get(string name)
{
return "name: " + name;
}
}

{id:int:min(2)}路由必须使用min(2),否则对于id = 0id = 1会有冲突。

运行程序,当路由是api/Test/0api/Test/1api/Test/Trueapi/Test/False的时候,匹配我们的自定义约束。

当路由是api/Test/{大于2的整数}的时候,匹配第二个路由。

其他情况匹配第三个路由。

结论

路由约束在某些场景下是非常有用的功能,可以减少controller中校验参数,将部分参数校验的功能使用声明式的attruibute来实现,某些重复的校验可以通过抽取成约束公共使用。

constraint的构造函数可以使用注入,所以可以扩展性十分强,可以通过查询数据库做一些参数校验。

官网上对于路由约束只是简单的提了一下,本文对路由约束的使用提供了具体的示例。

ASP.NET Core中自定义路由约束的更多相关文章

  1. 在ASP.NET Core中构建路由的5种方法

    原文链接 :https://stormpath.com/blog/routing-in-asp-net-core 在ASP.NET Core中构建路由的5种方法 原文链接 :https://storm ...

  2. C#调用接口注意要点 socket,模拟服务器、客户端通信 在ASP.NET Core中构建路由的5种方法

    C#调用接口注意要点   在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存c ...

  3. 如何在ASP.NET Core中自定义Azure Storage File Provider

    文章标题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p ...

  4. .NET Core中的路由约束

    背景介绍 上周给大家分享了Nancy in .NET Core学习笔记 - 路由之后, 就一直在考虑.NET Core能否实现和Nancy中一样的路由约束, 最近查阅了一下MSDN及一些国外博客, 发 ...

  5. asp.net core 中的路由

  6. ASP.NET Core 中的SEO优化(3):自定义路由匹配和生成

    前言 前两篇文章主要总结了CMS系统两个技术点在ASP.NET Core中的应用: <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET ...

  7. ASP.NET Core中使用自定义路由

    上一篇文章<ASP.NET Core中使用默认MVC路由>提到了如何使用默认的MVC路由配置,通过这个配置,我们就可以把请求路由到Controller和Action,通常情况下我们使用默认 ...

  8. ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由

    原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...

  9. (9)ASP.NET Core 中的MVC路由二

    1.URL生成 MVC应用程序可以使用路由的URL生成功能,生成指向操作(Action)的URL链接. IUrlHelper 接口用于生成URL,是MVC与路由之间的基础部分.在控制器.视图和视图组件 ...

随机推荐

  1. oracle中文乱码的解决方法

    select userenv('language') from dual; NLS_LANG AMERICAN_AMERICA.AL32UTF8

  2. vue浏览器滚动加载更多

    created () { var that = this; window.addEventListener('scroll',this.scroll,true) console.log(this.$r ...

  3. Redis核心原理

    Redis系统介绍: Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b Redis的基础数据结构与使用:https://www.jian ...

  4. python狂犬病大数据分析

    一.被动物咬伤.抓伤者,年龄以45-59岁年龄组为最多(占30.66%). 45-59岁年龄段的人与动物接触较多.被侵害的机会最多.其次受伤机会较多的是15-44岁年龄阶段的人,而7岁及以下儿童受伤比 ...

  5. 部分用户访问Polycom视频会议时故障

    1.现象 Polycom视频会议服务器部署在防火墙下,通过Paloalto防火墙的一对一映射到公网. 部分同事使用职场网络或者4G通过公网访问时,出现超时问题. 2.分析: Polycom设备并没有做 ...

  6. 54. Spiral Matrix以螺旋顺序输出数组

    [抄题]: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spi ...

  7. 156. Binary Tree Upside Down反转二叉树

    [抄题]: Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left nod ...

  8. react 子元素修改父元素值的一个偏方,虽然简单,但是不建议用,

    this.state.obj = { name: "小明" } <Zizujian obj={this.state.obj} /> // 子组件这样修改父元素的值 // ...

  9. bittorrent 学习(一) 种子文件分析与bitmap位图

    终于抽出时间来进行 BITTORRENT的学习了 BT想必大家都很熟悉了,是一种文件分发协议.每个下载者在下载的同时也在向其他下载者分享文件. 相对于FTP HTTP协议,BT并不是从某一个或者几个指 ...

  10. solr7.7.0搜索引擎使用(一)(下载安装)

    一.下载安装 可以直接在官网下载地址:https://lucene.apache.org/solr/ 解压之后,目录结构如下图,bin里边提供部署的文件,contrib提供额外的jar包,docs提供 ...