用破折号路由值

时间:2012-12-28 20:00:52

标签: asp.net asp.net-mvc asp.net-mvc-3 routing asp.net-mvc-routing

我有这条路线:

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

这条路线适用于网址:

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

但是没有为url工作:

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

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

EDITED

这样的路线:

"News/{id}_{alias}"

适用于两个网址:

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

1 个答案:

答案 0 :(得分:3)

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

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

  1. 使用除破折号之外的其他内容。正如您所指出的那样,将破折号和连字符结合起来。
  2. 采用flem方法并在控制器操作中的id和别名内进行解析
  3. 您可以创建一个自定义Route,它将重新解析。例如,将id = 6-nice, alias = news转换为id = 6, alias = news-nice
  4. 我将向您展示一个原始的(没有任何错误处理或良好的编码实践!)选项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()));