ASP.NET Core中自定义路由约束
路由约束
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 = id,value = 1。当然还有其他的变量的值,比如controller,action等。
第五个参数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.cs的ConfigureServices方法添加自定义约束:
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 = 0或id = 1会有冲突。
运行程序,当路由是api/Test/0、api/Test/1、api/Test/True和api/Test/False的时候,匹配我们的自定义约束。
当路由是api/Test/{大于2的整数}的时候,匹配第二个路由。
其他情况匹配第三个路由。
结论
路由约束在某些场景下是非常有用的功能,可以减少controller中校验参数,将部分参数校验的功能使用声明式的attruibute来实现,某些重复的校验可以通过抽取成约束公共使用。
constraint的构造函数可以使用注入,所以可以扩展性十分强,可以通过查询数据库做一些参数校验。
官网上对于路由约束只是简单的提了一下,本文对路由约束的使用提供了具体的示例。
ASP.NET Core中自定义路由约束的更多相关文章
- 在ASP.NET Core中构建路由的5种方法
原文链接 :https://stormpath.com/blog/routing-in-asp-net-core 在ASP.NET Core中构建路由的5种方法 原文链接 :https://storm ...
- C#调用接口注意要点 socket,模拟服务器、客户端通信 在ASP.NET Core中构建路由的5种方法
C#调用接口注意要点 在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存c ...
- 如何在ASP.NET Core中自定义Azure Storage File Provider
文章标题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p ...
- .NET Core中的路由约束
背景介绍 上周给大家分享了Nancy in .NET Core学习笔记 - 路由之后, 就一直在考虑.NET Core能否实现和Nancy中一样的路由约束, 最近查阅了一下MSDN及一些国外博客, 发 ...
- asp.net core 中的路由
- ASP.NET Core 中的SEO优化(3):自定义路由匹配和生成
前言 前两篇文章主要总结了CMS系统两个技术点在ASP.NET Core中的应用: <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET ...
- ASP.NET Core中使用自定义路由
上一篇文章<ASP.NET Core中使用默认MVC路由>提到了如何使用默认的MVC路由配置,通过这个配置,我们就可以把请求路由到Controller和Action,通常情况下我们使用默认 ...
- ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
- (9)ASP.NET Core 中的MVC路由二
1.URL生成 MVC应用程序可以使用路由的URL生成功能,生成指向操作(Action)的URL链接. IUrlHelper 接口用于生成URL,是MVC与路由之间的基础部分.在控制器.视图和视图组件 ...
随机推荐
- CSS表单3 光标样式 (每个位置鼠标放上去的样式不同)
<!DOCTYPE html> <html> <head> <title>单选按钮对齐</title> ...
- wiredtiger--初学数据恢复
启动mongodb是failed,日志如下 1.解压wirdtiger包 tar -vxf wiredtiger-3.1.0.tar.bz2 -C /home/wiredtiger/ 2.安装snap ...
- python爬虫小说代码,可用的
python爬虫小说代码,可用的,以笔趣阁为例子,python3.6以上,可用 作者的QQ:342290433,汉唐自远工程师 import requests import refrom lxml i ...
- C语言变量声明内存分配
转载: C语言变量声明内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结 ...
- python note 03 切片及对字符串操作
1.计算 1 - 2 + 3 ... + 99 中除了88以外的数之和 i = 1 sum = 0 while i < 100 : if i == 88 : i = i + 1 continue ...
- [leetcode]42. Trapping Rain Water雨水积水问题
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- Centos7+hadoop2.7.3+jdk1.8
修改主机名 1. 修改主机名 vi /etc/sysconfig/network ,改为 master , slave1 , slave2 2. source /etc/sy ...
- javascript 新建实例对象
在main js里面new 这样一个实例算怎么回事,如果不这么new, ToolBar里就会报错: Portal.gbl = { constants : new Portal.common.Const ...
- centos 7 添加中文输入法
中文输入法
- PHP开发——变量
变量的概念 l 变量是临时存储数据的容器: l 变量是存储内存当中: l 我们现实中有很多数据:姓名.性别.年龄.学历等: l 在计算机中,用变量来代替一个一个的数据: l 我们可以把计算机 ...