一般情况下,有些时候可能需要定义一些约束的值,比如Length(1,10)来表示1-10之间的字符串长度,举例来说,加入我们要定义一个4个参数的约束规则,如abcd(1,10,20,30)来表示一个特殊的验证项,则需要声明有4个参数的构造函数,示例如下:
public class ABCDRouteConstraint : IRouteConstraint { public int A { get; private set; } public int B { get; private set; } public int C { get; private set; } public int D { get; private set; } public ABCDRouteConstraint(int a, int b, int c, int d) { A = a;B = b;C = c;D = d; } public bool Match(HttpContext httpContext, IRouter route, string routeKey, IDictionary<string, object> values, RouteDirection routeDirection) { bool b = false; object value; if (values.TryGetValue(routeKey, out value) && value != null) { var valueString = value.ToString();//这里需要进行进一步的验证工作 return true; } return b; } }
假如你在Action上了定义了如下约束:
[Route("index/{productId:abcd(1,20,30,40)}")]
那么,在注册该约束类型以后,系统启动厚扫描所有的Route进行注册的时候,会分析你定义的这4个值,然后会将这4个值赋值给该路由对应的约束实例上的A、B、C、D四个属性上,以便在HTTP请求过来的时候,分析URL上的值,看是否符合Match里定义的规则(在验证的时候就可以使用这4个属性值)。
默认约束的所有代码可以参考: https://github.com/aspnet/Routing/tree/dev/src/Microsoft.AspNet.Routing/Constraints
另外,如果定义了4个参数的约束,那么在action上定义路由的时候则必须符合参数的数据类型,如果不符合,系统启动的时候就会出错,示例错误如下:
[Route("index/{productId:abcd}")] //没有为该对象定义无参数的构造函数 [Route("index/{productId:abcd(a)}")] [Route("index/{productId:abcd('a')}")] //输入字符串的格式不正确 [Route("index/{productId:abcd(1,2,3)}")] //构造函数的参数个数和定义的参数个数不一致。
如果你定义的参数类型是字符串类型,则下面2种形式的定义都是合法的:
[Route("index/{productId:abcd(a,b,c,d)}")] [Route("index/{productId:abcd('a','b','c','d')}")]