我设置了以下路线:
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开头,则使用索引操作将转换为单个路径?
答案 0 :(得分: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
对它们进行装饰,这样就无法通过您的默认路线获取它们,您可能也可以使用它们......
答案 1 :(得分: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" } }
);
此外,您可以将其重复用于其他类似情况。希望这有帮助