带破折号的路由值

Ale*_*ack 6 asp.net asp.net-mvc routing asp.net-mvc-routing asp.net-mvc-3

我有这条路线:

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

这条路线适用于这样的网址:

http://localhost:54010/News/6-news
Run Code Online (Sandbox Code Playgroud)

但不适用于这样的网址:

http://localhost:54010/News/6-nice-news
Run Code Online (Sandbox Code Playgroud)

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

已编辑

路线是这样的:

"News/{id}_{alias}"
Run Code Online (Sandbox Code Playgroud)

适用于两个网址:

http://localhost:54010/News/6_news
http://localhost:54010/News/6_nice-news
Run Code Online (Sandbox Code Playgroud)

nem*_*esv 4

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

因此该 urlhttp://localhost:54010/News/6-news会生成以下标记:

id = 6, alias = news
Run Code Online (Sandbox Code Playgroud)

但会http://localhost:54010/News/6-nice-news生成以下令牌:

id = 6-nice, alias = news
Run Code Online (Sandbox Code Playgroud)

并且id = 6-nice令牌将使您的路由约束失败@"^[0-9]+$".,因此您将得到 404。

现在可以配置 MVC 的这种行为,因此您有以下选项:

  1. 使用破折号以外的其他内容。正如您所指出的,组合破折号和连字符是有效的。
  2. 采用 flem 方法并解析控制器操作中的 id 和别名
  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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你只需要注册你的路线:

routes.Add("News",
            new MyRoute("News/{id}-{alias}",
            new RouteValueDictionary(new {controller = "News", action = "Show"}),
            new RouteValueDictionary(new
                                        {
                                             id = @"^[0-9]+$"
                                        }),
            new RouteValueDictionary()));
Run Code Online (Sandbox Code Playgroud)