【问题标题】:Route always goes to the first maproute路线总是去第一个地图路线
【发布时间】:2011-03-07 06:04:21
【问题描述】:

我正在尝试创建看起来像这样的 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/Add 时,它总是将桌面浏览器从/en/User/List 重定向到/mobile/en/User/Add。 移动版可以正常工作,但我相信这是因为第一个“移动”路由总是被视为匹配的路由,即使它在开始时没有 /mobile/。

我正在尝试为两个版本使用相同的 Controller,但我一直坚持它总是重定向到 Mobile 路由。这意味着RedirectToRoute 不是完美的,因为我想要动态路由。

感谢您的帮助。

【问题讨论】:

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


    【解决方案1】:

    主要问题是您提供的路由值与两条路由匹配,这意味着它将采用第一个(移动)。

    您可以通过重定向到路由而不是操作来手动选择要使用的路由。

    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 的技巧显然是不可取的。除了丑陋(hack)之外,它还可能导致大量代码重复。

    但是有可能为路由添加值,这些值可以从您的控制器(或视图)轻松获取:

    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);
        }
    }
    

    希望这能很好地解决您的问题!

    【讨论】:

    • 感谢 René,这看起来正是我希望做的。你能告诉我在哪里放置扩展方法最好吗?
    • 把静态类 ControllerExtensions 放在你想要的任何地方。在你想使用重定向的控制器中,确保包含扩展类所在的命名空间。然后在你的控制器中的任何地方你都可以使用 this.CusomRedirectToRoute("Home", "Index", routeValues);如果您愿意,还可以添加另一个扩展方法,将 null 作为 routeValues 值。
    • 如果你想整理一下,我评论的后半部分可以换成这篇文章中描述的用于获取路线名称的整洁干净的系统:stackoverflow.com/questions/363211/…
    【解决方案2】:

    嘿,您可能想在这篇文章中查看分组控制器: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx

    希望对您有所帮助。我们在工作中使用它并且运行良好

    【讨论】:

    • 感谢您的链接。如果我扩展项目,这是需要考虑的事情。
    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多