ASP.NET Core MVC中的路由约束


路由约束

路由约束是路由中的一种设置,可以帮助我们限制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方法中使用

C# 全选
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id:int}");

在路由属性中使用

C# 全选
[Route("Home/Index/{id:int}")]
public string Index(int id)
{
    return "I got " + id.ToString();
}

使用MapRoute方法带Constraint参数的重载

除了行内约束,我们还可以在Startup.cs的中通过app.UseMvc()方法来添加约束。

例:

C# 全选
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类,代码如下:

C# 全选
[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约束,方法如下:

C# 全选
[HttpGet]
[Route("~/api/posts/{email:email}")]
public IActionResult GetPostByEmail(string email)
{
	return Content("Coming from GetPostByEmail");
}

我们希望当posts后面的参数是email格式的时候,显示"Coming from GetPostByEmail"。

这里我们首先添加一个EmailConstraint类,并实现IRouteConstraint接口的Match方法

C# 全选
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。

C# 全选
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"。

ASP.NET Core MVC中的路由约束

 

原文链接:https://www.cnblogs.com/lwqlun/p/9649774.html

 

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:asp.net core MVC路由添加.html伪静态url时报错
下一篇:C# MEF插件化开发
评论列表

发表评论

评论内容
昵称:
关联文章

ASP.NET Core MVC约束
asp.net core MVC添加.html伪静态url时报错
asp.net - 在 ASP.NET Core MVC 嵌套 TagHelper
ASP.NET MVCASP.NET Core MVC获取当前URL/Controller/Action
ASP.NET Core MVC 在过滤器ActionFilter保存页面生成html静态页面文件
ASP.NET MVC快速入门(一)
配置
asp.net core mvc修改cshtml试图热加载动态更新
ASP.NET+MVC入门踩坑笔记 (一) 创建项目 项目配置运行 以及简单Api搭建
ASP.NET Core官网教程,资料查找
跳转以及参数处理
.NET Core MVC中间件使用记录日志
YESWEB 开发框架 配置文件 作用原理
【推荐】Razor文件编译 ASP.NET Core
.NET Core MVC 实现长时间任务进度显示
ASP.NET Core 读取Post Request.Body 正确姿势
ASP.NET Core web API使用Swagger/OpenAPI(Swashbuckle)
asp.net core 支持多种身份认证方式
.net core MVC页面源码文件文被编码
在SAP UI5应用程序配置文件之【配置】

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码