3

我有以下路线:

context.MapRoute(
    "content",
    "{page}/{title}",
    new { controller = "Server", action = "Index" },
    new { page = @"^[AFL][0-9A-Z]{4}$" }
);

此路由用于以下页面:

/A1234
/F6789
/L0123

然而它也抓住了:/Admin这是我不想要的。

我放置了一个临时解决方案,如下所示:

context.MapRoute(
    "content",
    "{page}/{title}",
    new { controller = "Server", action = "Index" },
    new { page = @"^[AFL][0-9][0-9A-Z]{3}$" }
);

这只有效,因为现在我所有的页面在第二个数字中都有一个 0。

有没有一种方法可以配置我的路由以接受 A、F 或 L 后跟 4 个大写字符但它不能捕获“dmin”?

不确定是否是这种情况,但我认为正则表达式不应该接受“dmin”,因为它是小写的,我只指定 AZ。但是,当用作 MVC 路由时,它确实需要“dmin”。有谁知道 ASP MVC 是否在内部将其转换为全大写?

4

2 回答 2

7

方案一:自定义路由约束类

默认路由处理在匹配 URL 时会忽略大小写(参见下面的代码),这就是您的案例中的Admin也匹配的原因。您应该做的就是编写一个自定义路由约束类,该类实现IRouteConstraint接口并Match适当地实现方法以区分大小写。

这是一个让您入门的教程

解决方案 2:自定义Route

如果您查看默认Route类如何处理约束,这是代码:

protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
    IRouteConstraint routeConstraint = constraint as IRouteConstraint;

    // checks custom constraint class instances
    if (routeConstraint != null)
    {
        return routeConstraint.Match(httpContext, this, parameterName, values, routeDirection);
    }

    // No? Ok constraint provided as regular expression string then?
    string text = constraint as string;
    if (text == null)
    {
        throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("Route_ValidationMustBeStringOrCustomConstraint"), new object[]
        {
            parameterName,
            this.Url
        }));
    }
    object value;
    values.TryGetValue(parameterName, out value);
    string input = Convert.ToString(value, CultureInfo.InvariantCulture);
    string pattern = "^(" + text + ")$";

    // LOOK AT THIS LINE
    return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
}

最后一行实际上匹配提供的正则表达式路由约束。如您所见,它忽略了大小写。所以第二种可能的解决方案是编写一个Route继承自这个默认Route类的新类并覆盖ProcessConstraint方法以忽略大小写。其他一切都可以保持不变。

于 2012-10-22T10:13:14.000 回答
0

另一种选择是这样的正则表达式:

@"^(?!Admin)[AFL][0-9][0-9A-Z]{3}$"

在尝试其余的正则表达式之前,这将排除 Admin 作为可能的匹配项。

于 2013-02-01T00:26:37.447 回答