ASP.NET Core中自定义路由约束

简介: ASP.NET Core中自定义路由约束路由约束ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值、可选和约束。约束的使用方法是在属性路由上添加指定的约束名,用法如下:// 单个使用[Route("users/{id:int}")]public U...

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(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的构造函数可以使用注入,所以可以扩展性十分强,可以通过查询数据库做一些参数校验。

官网上对于路由约束只是简单的提了一下,本文对路由约束的使用提供了具体的示例。
原文地址https://www.cnblogs.com/Weilence/p/10587924.html

相关文章
|
6天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:<https://github.com/khellang/Scrutor>
25 5
|
24天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
35 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
14天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
2月前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
46 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
74 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
55 0
|
4月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
|
4月前
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
142 0