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

 更新时间£º2019年03月25日 09:27:35   作者£ºweilence   我要评论

这篇文章主要介绍了ASP.NET Core中自定义路由约束的实现£¬文中通过示例代码介绍的非常详细£¬对大家的学习或者工作具有一定的参考学习价值£¬需要的朋友们下面随着小编来一起学习学习吧

路由约束

ASP.NET Core中£¬通过定义路由模板£¬可以在Url上传递变量£¬同时可以针对变量提供默?#29616;µ¡?#21487;选和约束¡£

约束的使用方法是在属性路由上添加指定的约束名£¬用法如下£º

// 单个使用
[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匹配的?#20540;?#20540;£¬例如文章开头的示例的路由£¬如果Url是 users/1 £¬那么就有一个?#20540;ä£?#20854; 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的整数} 的时候£¬匹配第二个路由¡£

其他情况匹配第三个路由¡£

结论

路由约束在某些场景下是非常有用的功能£¬可?#32422;?#23569; controller 中校验参数£¬将部分参数校验的功能使用声明式的 attruibute 来实现£¬某些重复的校验可以通过抽取成约束公共使用¡£

constraint 的构造函数可以使用注入£¬所以可以扩展性十分强£¬可以通过查询数据库做一些参数校验¡£

官网上对于路由约束只是简单的提了一下£¬本文对路由约束的使用提供了具体的示例¡£

以上就是本文的全部内容£¬希望对大家的学习有所帮助£¬也希望大家多多支持脚本之家¡£

相关文章

  • 获取DataList控件的主键和索引实用图解

    获取DataList控件的主键和索引实用图解

    一是在DataList控件添加一个DataKeyField£¬以便获取到它的主键值£¬另外还添加了两个铵钮及一个Label标答£¬用来显示选择结果£¬真正将来你也许用不上标签£¬因为获取到结果之后£¬就可以进?#24515;?#24819;的要事情了
    2013-01-01
  • ASP.NET中画图形验证码的实现代码

    ASP.NET中画图形验证码的实现代码

    这篇文章给大家介绍了asp.net中画图形验证码的实现方法£¬代码简单易懂£¬非常不错£¬具有参考借鉴价值£¬需要的朋友参考下
    2017-01-01
  • asp.net更新指定记录的方法

    asp.net更新指定记录的方法

    这篇文章主要介绍了asp.net更新指定记录的方法,涉及针对指定ID调用update语句的方法,是非常实用的技巧,需要的朋友可以参考下
    2014-11-11
  • C#后台调用前台javascript的五种方法小结

    C#后台调用前台javascript的五种方法小结

    于项目需要£¬用到其他项目组用VC开发的组件£¬在web后台代码无法访问这个组件£¬所以只好通过后台调用前台的javascript£¬从而操作这个组件¡£
    2010-12-12
  • asp.net使用for循环实现Datalist的分列显示功能

    asp.net使用for循环实现Datalist的分列显示功能

    工程?#23548;?-用for循环代替了DataList多列显示£¬得到2行四列的表格£¬需要内存表的8行数据
    2009-12-12
  • asp.net下利用JS实现对后台CS代码的调用方法

    asp.net下利用JS实现对后台CS代码的调用方法

    asp.net下利用JS实现对后台CS代码的调用方法...
    2007-04-04
  • ASP.NET中操作数据库的基本步骤分享

    ASP.NET中操作数据库的基本步骤分享

    ASP.NET中操作数据库的基本步骤分享£¬学习asp.net的朋友可以参考下¡£
    2011-10-10
  • 最新评论

    常用在线小工具

    ÁÉÄþ35Ñ¡7¿ª½±½á¹û