我正在尝试创建看起来像这样的URI:
移动设备http://hostname/mobile/en/controller/action
或桌面(非移动设备)http://hostname/en/controller/action
。
我的路线表目前看起来像这样(Global.asax.cs)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Mobile", // Route name
"mobile/{language}/{controller}/{action}/{id}", // URL with parameters
new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
当我尝试做的时候会出现问题
return RedirectToAction("Add", "User");
当我希望桌面浏览器转到/en/User/List
时,它始终会将桌面浏览器从/mobile/en/User/Add
重定向到/en/User/Add
。
移动版本可以正常工作,但我相信这是因为第一条“移动”路由始终被认为是匹配的路由,即使它在开始时没有/ mobile /。
我正在尝试为两个版本使用相同的控制器,但我坚持使用它总是重定向到 Mobile 路由。这意味着RedirectToRoute
并不完美,因为我想要动态路线。
感谢您的帮助。
答案 0 :(得分:2)
主要问题是您提供的路线值与两条路线相匹配,这意味着它将采用第一条路线(可移动)。
您可以通过重定向到路由而不是操作来手动选择要使用的路由。
return RedirectToRoute("Mobile", new {
language = "en", controller = "User", action = "Get", id = 20
});
适用于移动设备或
return RedirectToRoute("Default", new {
language = "en", controller = "User", action = "Get", id = 20
});
表示您的默认路线。
但是,这会给您带来一个新问题:获取当前路由的名称。如示例中所示,引用命名路由非常有可能。然而,获取当前使用的路线的名称似乎是不可能的。使用类似于查看当前URI的黑客显然是不可取的。除了丑陋(黑客)之外,它还可能导致大量代码重复。
但是有可能在路径中添加值,这些值可以从控制器(或视图)轻松获得:
routes.MapRoute(
"Mobile", // Route name
"mobile/{language}/{controller}/{action}/{id}", // URL with parameters
new { routeName = "Mobile", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { routeName = "Default", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
现在,从您的代码中,您可以使用路由本身提供的值重定向到当前路由:
return RedirectToRoute(RouteData.Values["routeName"], new {
language = "en", controller = "User", action = "Get", id = 20
});
现在,如果你想让这个完全看上去,你甚至可以用这个方法制作一个扩展方法:
public static class ControllerExtensions {
public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, object routevalues) {
return CustomRedirectToRoute(controller, controllerName, actionName, new RouteValueDictionary(routevalues));
}
public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, RouteValueDictionary routevalues) {
routevalues = routevalues ?? new RouteValueDictionary();
routevalues.Add("controller", controllerName);
routevalues.Add("action", actionName);
return new RedirectToRouteResult(controller.RouteData.Values["routeName"] as string, routevalues);
}
}
希望这为您的问题提供了一个很好的解决方案!
答案 1 :(得分:0)
嘿,你可能想在这篇文章中查看分组控制器: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx
希望它有所帮助。我们在工作中使用它并且进展顺利