在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
路由约束 ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值、可选和约束。 约束的使用方法是在属性路由上添加指定的约束名,用法如下: // 单个使用 [Route("users/{id:int}")] public User GetUserById(int id) { } // 组合使用 [Route("users/{id:int:min(1)}")] public User GetUserById(int id) { } 框架内部已经提供了一些约束,如下所示:
内置的约束能够适用于大部分常见的应用场景,但是有时候我们还是需要去自定义我们想要的效果。 自定义路由约束 自定义约束是要实现 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 的构造函数可以使用注入,所以可以扩展性十分强,可以通过查询数据库做一些参数校验。 官网上对于路由约束只是简单的提了一下,本文对路由约束的使用提供了具体的示例。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持极客世界。 |
请发表评论