6

我有这条路线:

            routes.MapRoute(
            "News",
            "News/{id}-{alias}",
            new { controller = "News", action = "Show" },
            new
                {
                    id = @"^[0-9]+$"
                },
            namespaces: new[] { "Site.Controllers" }
        );

这条路线适用于 url,如下所示:

http://localhost:54010/News/6-news

但不适用于这样的网址:

http://localhost:54010/News/6-nice-news

如何在我的路线值“别名”中使用破折号?

已编辑

路线如下:

"News/{id}_{alias}"

适用于两个网址:

http://localhost:54010/News/6_news
http://localhost:54010/News/6_nice-news
4

1 回答 1

4

问题出在您的模式上:News/{id}-{alias}因为路由正在贪婪地解析模式。

因此 urlhttp://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 的这种行为,因此您有以下选项:

  1. 使用破折号以外的东西。正如您所指出的,将破折号和连字符结合使用是可行的。
  2. 采用 flem 方法并在控制器操作中解析 id 和 alias
  3. 您可以创建一个Route将进行重新解析的自定义。例如转换 id = 6-nice, alias = newsid = 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()));
于 2012-12-28T20:44:15.503 回答