【问题标题】:Route value with dashes带破折号的路由值
【发布时间】:2012-12-14 01:07:35
【问题描述】:

我有这条路线:

            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

【问题讨论】:

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


    【解决方案1】:

    问题在于您的模式: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 的这种行为,因此您有以下选择:

    1. 使用破折号以外的其他内容。正如您所指出的,将破折号和连字符结合使用是可行的。
    2. 采用 flem 方法并在控制器操作中解析 id 和别名
    3. 您可以创建一个自定义的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()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2015-11-29
      • 1970-01-01
      相关资源
      最近更新 更多