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 开头,则进入一个带有 Index 操作的单个路由?

4

2 回答 2

1

因此,如果我理解正确,您只需要一条路线来涵盖所有三项并指向Index行动?如果这是问题而不是答案

你当然可以

您只需将正则表达式更改为以下路由定义:

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

如您所见,这三个方法具有相同的签名,就好像它们是控制器操作一样,但它们不是,因为它们是private. 您可以将它们设置为private或装饰它们,NonActionAttribute这样它们就不会被您的默认路线拾取,您可能也有...

于 2012-09-01T20:15:39.723 回答
1

您仍然可以拥有三个路由,但通过为 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 回答