背景介绍
上周给大家分享了Nancy in .NET Core学习笔记 - 路由之后, 就一直在考虑.NET Core能否实现和Nancy中一样的路由约束, 最近查阅了一下MSDN及一些国外博客, 发现.NET Core中已经实现了相同的功能,所以这里给大家分享一下。
路由约束
路由约束是路由中的一种设置,可以帮助我们限制Url中的参数类型,只有当参数符合约束条件的时候,action才会被激活并触发。
比如我们现在有以下2个Url
[GET] /api/posts/{id}
[GET] /api/posts/{name}
我们希望当Posts后面的参数是int类型的时候触发第一个Url所指向action, 参数是string类型的时候触发第二个Url所指向的action。
在这种场景下,我们就需要使用路由约束。
如何添加路由约束
在.NET Core中有2种添加路由约束的方法。
- 行内约束(Inline Constraint)
- 使用MapRoute方法带Constraint参数的重载
当路由引擎发现当前的请求Url符合某个路由设置之后,就会去触发当前路由设置中的所有路由约束,当所有的约束都返回true, 这个路由对应的action就会被激活。
行内约束(Inline Constraint)
所谓的行内约束,即在路由Url模板中直接定义。定义的方式是在参数后面加冒号,并制定约束类型。
例:
"/api/posts/{id:int}"
所以该方式既可以在MapRoute方法中使用,也可以在路由属性中使用。
在MapRoute方法中使用
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id:int}");
在路由属性中使用
[Route("Home/Index/{id:int}")]
public string Index(int id)
{
return "I got " + id.ToString();
}
使用MapRoute方法带Constraint参数的重载
除了行内约束,我们还可以在Startup.cs的中通过app.UseMvc()方法来添加约束。
例:
using Microsoft.AspNetCore.Routing.Constraints;
app.UseMvc(routes =>
{
routes.MapRoute("default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index" },
new { id = new IntRouteConstraint() });
});
.NET Core内置的路由约束
.NET Core已经提供了很多基础的路由约束,总体上分为3种类型。
- 检查数据类型的约束
- 检查数据的值/长度/范围的约束
- 正则表达式约束
检查数据类型的约束
约束 | 行内 | Constraint类 | 说明 |
---|---|---|---|
int | {id:int} |
IntRouteConstraint |
只允许int32整数 |
alpha | {id:alpha} |
AlphaRouteConstraint |
只能包含大小写字母 |
bool | {id:bool} |
BoolRouteConstraint |
只允许布尔类型 |
datetime | {id:datetime} |
DateTimeRouteConstraint |
只允许日期格式 |
decimal | {id:decimal} |
DecimalRouteConstraint |
只允许decimal类型 |
double | {id:double} |
DoubleRouteConstraint |
只允许double类型 |
float | {id:float} |
FloatRouteConstraint |
只允许float类型 |
guid | {id:guid} |
GuidRouteConstraint |
只允许guid类型 |
检查数据的值/长度/范围的约束
约束 | 行内 | Constraint类 | 说明 |
---|---|---|---|
length(length) | {id:length(12)} |
LengthRouteConstraint |
字符串长度限制 |
maxlength(value) | {id:maxlength(8)} |
MaxLengthRouteConstraint |
字符串最大长度限制 |
minlength(value) | {id:minlength(4)} |
MinLengthRouteConstraint |
字符串最小长度限制 |
range(min,max) | {id:range(18,120)} |
RangeRouteConstraint |
数值范围限制 |
min(value) | {id:min(18)} |
MinRouteConstraint |
最小数值限制 |
max(value) | {id:max(120)} |
MaxRouteConstraint |
最大数值限制 |
正则表达式约束
约束 | 行内 | Constraint类 | 说明 |
---|---|---|---|
regex(expression) | {ssn:regex(^\d{{3}}-\d{{2}}-\d{{4}}$)}/ |
RegexRouteConstraint |
正则表达式约束 |
自定义路由约束
和Nancy一样,.NET Core也支持自定义路由约束,我们可以通过实现IRouteConstraint
接口的Match
方法来自定义路由约束。
我们举一个和之前Nancy in .NET Core学习笔记 - 路由中的类似的例子。
当前我们有一个PostController
类,代码如下:
[ApiController]
public class PostController : ControllerBase
{
[HttpGet]
[Route("~/api/posts/{id:int}")]
public IActionResult GetPostById(int id)
{
return Content("Coming from GetPostById");
}
[HttpGet]
[Route("~/api/posts/{name:alpha}")]
public IActionResult GetPostByName(string name)
{
return Content("Coming from GetPostByName");
}
}
这时候我们添加新的action方法GetPostByEmail, 并追加一个email约束,方法如下:
[HttpGet]
[Route("~/api/posts/{email:email}")]
public IActionResult GetPostByEmail(string email)
{
return Content("Coming from GetPostByEmail");
}
我们希望当posts后面的参数是email格式的时候,显示"Coming from GetPostByEmail"。
这里我们首先添加一个EmailConstraint
类,并实现IRouteConstraint
接口的Match
方法
public class EmailConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
if (route == null)
throw new ArgumentNullException(nameof(route));
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
object routeValue;
if (values.TryGetValue(routeKey, out routeValue))
{
var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);
return parameterValueString.Contains("@");
}
return false;
}
}
其中values.TryGetValue(routeKey, out routeValue)
是尝试从路由参数列表中,取出当前参数的值, 如果当前值中包含@, 我们就简单的认为这个Email约束通过, 并返回true。
上述代码完成之后,我们打开Startup.cs文件, 在ConfigureServices
方法中, 我们将这个自定义的路由约束添加到约束列表中,并指定当前的约束名称是email。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add("email", typeof(EmailConstraint));
});
}
最后我们看一下效果, 页面中正确显示除了"Coming from GetPostByEmail"。
参考文献
- Creating Custom Routing Constraint In ASP.NET Core MVC
- Routing in ASP.NET Core
- Route Constraints in ASP.NET Core
.NET Core中的路由约束的更多相关文章
-
ASP.NET Core中自定义路由约束
路由约束 ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值.可选和约束. 约束的使用方法是在属性路由上添加指定的约束名,用法如下: // 单个使用 [R ...
-
在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 ...
-
webapi中的路由约束
Route Constraints Route constraints let you restrict how the parameters in the route template are ma ...
- asp.net core 中的路由
-
ASP.NET Core的路由[5]:内联路由约束的检验
当某个请求能够被成功路由的前提是它满足某个Route对象设置的路由规则,具体来说,当前请求的URL不仅需要满足路由模板体现的路径模式,请求还需要满足Route对象的所有约束.路由系统采用IRouteC ...
-
ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
-
使用.NET Core在RESTful API中进行路由操作
介绍 当列出REST API的最佳实践时,Routing(路由)总是使它位于堆栈的顶部.今天,在这篇文章中,我们将使用特定于.NET Core的REST(web)API来处理路由概念. 对于新手API ...
-
(9)ASP.NET Core 中的MVC路由二
1.URL生成 MVC应用程序可以使用路由的URL生成功能,生成指向操作(Action)的URL链接. IUrlHelper 接口用于生成URL,是MVC与路由之间的基础部分.在控制器.视图和视图组件 ...
随机推荐
-
SqlServer 连接字符串多种配置
Application Name(应用程序名称):应用程序的名称.如果没有被指定的话,它的值为.NET SqlClient Data Provider(数据提供程序). AttachDBFilenam ...
-
iOS开发UI篇—Quartz2D简单使用(一)
iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: 1 // 2 // YYlineview.m 3 // 03-画直线 4 // 5 // Created by apple on ...
-
map(int, ..) 与 int() 的区别
>>> map(int,') [0] >>> int('-1') -1 >>> map(int, l[1]) Traceback (most re ...
-
Clojure学习05:谓词函数
谓词函数是一个判断式,一个返回bool值的函数. clojure中(lisp习惯)有个规定:对于判断功能的函数,函数名后面都有一个“?”号.所以只要看到后面带问号的函数名,就知道这一定是一个判断函数. ...
-
开涛spring3(2.3) - IoC的配置使用
2.3.1 XML配置的结构 一般配置文件结构如下: <beans> <import resource=”resource1.xml”/> <bean id=”bean ...
-
select * 和 select 所有字段的区别
阅读本文大概需要 1 分钟. 之前发过的文章中,关于 select * 和 select 所有字段的知识,有描述不恰当,这次重新纠正下,加深下理解. MySQL 5.1.37 表记录数 41,547, ...
-
使用Visual Studio Code开发.NET Core看这篇就够了
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9926078.html 在本文中,我将带着大家一步一步的通过图文的形式来演示如何在Visual Studi ...
-
移植busybox构建最小根文件系统
Busybox:瑞士军刀,里面装有很多小命令. STEP 1:构建目录结构 创建根文件系统目录,主要包括以下目录/dev /etc /lib /usr /var /proc /tmp /hom ...
-
Python(十三)python的函数重载
首先,重载函数的功能是实现参数不同情况下功能相同的函数. 函数重载的目的是解决功能相同的函数的以下问题: 1.参数的类型: 2.参数的个数: 对于情况1,函数功能呢相同,参数不同的情况. python ...
-
Win7 VS2013环境使用cuda_7.5.18
首先得吐槽下VS2015出来快一年了CUDA居然还不支持,没办法重装系统刚从2013升到2015,还得再装回一个2013用,只为学习CUDA... 然后安装的时候,如果你选择自定义组件安装,注意不要改 ...