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

しかし、次のようなURLでは機能しません。

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

ルート値「エイリアス」でダッシュをどのように使用しますか?

編集済み

このようなルート:

"News/{id}_{alias}"

両方のURLで機能します:

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とエイリアス内で解析します
  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 に答える