我有以下路线:
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”,因为它是小写的,我只指定A-Z。但是当用作MVC路由时,它确实需要“dmin”。有没有人知道ASP MVC内部是否将其转换为全部大写?
答案 0 :(得分:7)
默认路由处理会在匹配URL时忽略大小写(请参阅下面的代码),这也是您案例中 Admin 匹配的原因。您应该做的就是编写一个自定义路由约束类,该类实现IRouteConstraint
接口并适当地实现Match
方法以区分大小写。
Here's a tutorial to get you started
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
方法覆盖为不忽略大小写。其他一切都可以保持不变。
答案 1 :(得分:0)
另一种选择是像这样的正则表达式:
@"^(?!Admin)[AFL][0-9][0-9A-Z]{3}$"
在尝试使用正则表达式的其余部分之前,会将Admin排除在可能的匹配项之前。