Маршрут всегда идет к первому maproute - PullRequest
5 голосов
/ 23 июня 2010

Я пытаюсь создать 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 / в начале.

I'mпытаюсь использовать один и тот же контроллер для обеих версий, но я застрял на нем, всегда перенаправляя на маршрут Mobile .Это означает, что RedirectToRoute не является префектом, так как я хочу динамические маршруты.

Спасибо за вашу помощь.

Ответы [ 2 ]

2 голосов
/ 25 июня 2010

Основная проблема заключается в том, что предоставленные вами значения маршрутов совпадают с обоими маршрутами, что означает, что он займет первый (мобильный).

Вы можете вручную выбрать, какой маршрут использовать, перенаправив на маршрутывместо действий.

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

Надеемся, это поможет решить вашу проблему!

0 голосов
/ 23 июня 2010

Эй, вы можете проверить группировку контроллеров в этом посте: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx

Надеюсь, это полезно.Мы используем это на работе, и все идет хорошо

...