问题在于您的模式:News/{id}-{alias},因为路由正在贪婪地解析模式。
所以 url http://localhost:54010/News/6-news 生成以下标记:
id = 6, alias = news
但http://localhost:54010/News/6-nice-news 会生成以下令牌:
id = 6-nice, alias = news
而id = 6-nice 令牌将使您的路由约束@"^[0-9]+$". 失效,因此您将获得 404。
现在有一种方法可以配置 MVC 的这种行为,因此您有以下选择:
- 使用破折号以外的其他内容。正如您所指出的,将破折号和连字符结合使用是可行的。
- 采用 flem 方法并在控制器操作中解析 id 和别名
- 您可以创建一个自定义的
Route 来进行重新解析。例如将 id = 6-nice, alias = news 转换为 id = 6, alias = news-nice
我将向您展示选项 3 的原始实现(没有任何错误处理或良好的编码实践!)以帮助您入门。
所以你需要从Route继承:
public class MyRoute : Route
{
public MyRoute(string url,
RouteValueDictionary defaults,
RouteValueDictionary constraints,
RouteValueDictionary dataTokens)
: base(url, defaults, constraints, dataTokens, new MvcRouteHandler())
{
}
protected override bool ProcessConstraint(HttpContextBase httpContext,
object constraint, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
var parts = ((string) values["id"]).Split('-');
if (parts.Length > 1)
{
values["id"] = parts[0];
values["alias"] = // build up the alias part
string.Join("-", parts.Skip(1)) + "-" + values["alias"];
}
var processConstraint = base.ProcessConstraint(httpContext, constraint,
parameterName, values, routeDirection);
return processConstraint;
}
}
那么你只需要注册你的路线:
routes.Add("News",
new MyRoute("News/{id}-{alias}",
new RouteValueDictionary(new {controller = "News", action = "Show"}),
new RouteValueDictionary(new
{
id = @"^[0-9]+$"
}),
new RouteValueDictionary()));