1

次のルートを設定しています。

        context.MapRoute(
            "content_article",
            "A{rk}/{title}",
            new { controller = "Server", action = "Article" },
            new { rk = @"^[\dA-Z]{3}$" }
        );

        context.MapRoute(
            "content_contentBlock",
            "C{rk}/{title}",
            new { controller = "Server", action = "ContentBlock" },
            new { rk = @"^[\dA-Z]{3}$" }
        );

        context.MapRoute(
            "content_favoritesList",
            "F{rk}/{title}",
            new { controller = "Server", action = "FavoritesList" },
            new { rk = @"^[\dA-Z]{3}$" }
        );

私が組み合わせることができる方法はありますか?

"A{rk}/{title}",
"C{rk}/{title}",
"F{rk}/{title}",

URLがA、C、またはFで始まる場合に実行されるインデックスのアクションを使用して、単一のルートに変換しますか?

4

2 に答える 2

1

それで、私が正しく理解していれば、3つすべてをカバーし、Index行動を示すために1つのルートだけが必要ですか?それが答えよりも質問なら

できますよ

正規表現を次のルート定義に少し変更する必要があります。

context.MapRoute(
    "content",
    "{lrk}/{title}",
    new { controller = "Server", action = "Index" },
    new { lrk = @"^[ACF][0-9A-Z]{3}$" }
);

以上です。次に、最初の文字の解析は、適切な別のメソッドを実行する可能性が高い(そしてうまくいけば)インデックスアクションによって実行されます。

public ActionResult Index(string lrk)
{
    if (string.IsNullOrEmpty(lrk))
    {
        throw new ArgumentException("lrk")
    }
    char first = lrk[0];
    switch(first)
    {
        case 'A':
            return GetArticle(lrk.Substring(1));
        case 'C':
            return GetContent(lrk.Substring(1));
        case 'F':
            return GetFavorites(lrk.Substring(1));
        default:
            return View();
    }
}

private ActionResult GetArticle(string rk)
{
    ...
}

// and other couple

ご覧のとおり、3つのメソッドは、コントローラーアクションであるかのように同じシグネチャを持っていますが、そうであるため、そうではありませんprivate。あなたはそれらをとして設定するか、それらをprivate飾ることができNonActionAttributeますので、あなたはそれらをあなたがおそらく持っているデフォルトルートによって拾われないようにします...

于 2012-09-01T20:15:39.723 に答える
1

引き続き3つのルートを持つことができますが、RouteCollectionの拡張メソッドを追加することにより、それらの定義を簡素化します。

public class ActionMap : Dictionary<string, string>
    {}

    public static class RouteCollectionExtensions
    {
        public static void MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, ActionMap map)
        {
            if(!url.Contains("{action}")) throw new ArgumentException("{action} segment is required", url);

            foreach (var actionKey in map.Keys)
            {
                string routeName = string.Format("{0}_{1}", name, map[actionKey]);
                string routeUrl = url.Replace("{action}", actionKey);
                var routeDefaults = new RouteValueDictionary(defaults);
                routeDefaults["action"] = map[actionKey];

                Route route = new Route(routeUrl, new MvcRouteHandler())
                {
                    Defaults = routeDefaults,
                    Constraints = new RouteValueDictionary(constraints),
                    DataTokens = new RouteValueDictionary()
                };

                routes.Add(routeName, route);
            }
        }
    }

そして今、それらのルートの定義は次のようになります:

 routes.MapRoute(
                    "content",
                   "{action}{rk}/{title}",
                   new { controller = "Server" },
                   new { rk = @"^[\dA-Z]{3}$" },
                    new ActionMap { { "a", "Article" }, { "c", "ContentBlock" }, { "f", "FavoritesList" } }
            );

また、別の同様の状況で再利用できます。お役に立てれば

于 2012-09-01T20:31:54.887 に答える