路线始终转到第一个maproute

时间:2010-06-23 10:09:26

标签: c# asp.net-mvc asp.net-mvc-2 routing asp.net-mvc-routing

我正在尝试创建看起来像这样的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并不完美,因为我想要动态路线。

感谢您的帮助。

2 个答案:

答案 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

希望它有所帮助。我们在工作中使用它并且进展顺利