ASP.NET (MVC) интернационализация маршрутов - PullRequest
6 голосов
/ 03 июня 2011

Я искал решение для интернационализации / локализации маршрутов на веб-сайте ASP.NET MVC. Я наткнулся на сообщение в блоге Перевод маршрутов (ASP.NET MVC и Webforms) от Мартена Баллиау. Он представляет очень хорошее решение, которое прекрасно работает - пока в поле зрения не будет Html.RenderAction("...").

В основном он вводит TranslatedRoute наследование от System.Web.Routing.Route, что делает перевод с использованием словаря с переводами на лету.

Есть идеи, почему при вызове Html.RenderAction("...") все происходит иначе? Также кажется, что ошибка возникает только в том случае, если действие, которое должно быть выполнено, выполняется в том же контроллере.

А вот точная ошибка:

"Контроллер для пути '/ MyTranslatedControllerName' не найден или не реализует IController."

Обновление:

Вот моя конфигурация маршрутов (взятая из примера проекта Maarten, добавлены маршруты для Contact, который является частичной визуализацией):

    public static void RegisterRoutes(RouteCollection routes)
        {
            CultureInfo cultureEN = CultureInfo.GetCultureInfo("en-US");
            CultureInfo cultureDE = CultureInfo.GetCultureInfo("de-DE");
            CultureInfo cultureFR = CultureInfo.GetCultureInfo("fr-FR");

            DictionaryRouteValueTranslationProvider translationProvider = new DictionaryRouteValueTranslationProvider(
                new List<RouteValueTranslation> {
                    new RouteValueTranslation(cultureEN, "Home", "Home"),
                    new RouteValueTranslation(cultureEN, "About", "About"),
                    new RouteValueTranslation(cultureEN, "Contact", "Contact"),
                    new RouteValueTranslation(cultureDE, "Home", "Home"),
                    new RouteValueTranslation(cultureDE, "About", "About"),
                    new RouteValueTranslation(cultureDE, "Contact", "Kontakt"),
                    new RouteValueTranslation(cultureFR, "Home", "Demarrer"),
                    new RouteValueTranslation(cultureFR, "About", "Infos"),
                    new RouteValueTranslation(cultureFR, "Contact", "Contact")
                }
            );

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapTranslatedRoute(
                "TranslatedRoute",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = "" },
                new { controller = translationProvider, action = translationProvider },
                true
            );

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

Ответы [ 2 ]

4 голосов
/ 03 июня 2011

Это будет зависеть от конфигурации вашего маршрута. Вы можете поделиться этим?

РЕДАКТИРОВАТЬ: Кажется, что метод RenderAction использует «GetVirtualPath» на маршруте, чтобы определить URL для MvcHandler. Однако этот метод не вызывает метод GetRouteData.

Существует метод обнаружения этого: routeData.DataTokens ["ParentActionViewContext"] Проблема в том, что TranslatedRoute слишком поздно узнает об этом ...

Вкратце: я боюсь, что это невозможно при текущей реализации ChildActionExtensions.ActionHelper в System.Web.Mvc ...

У меня есть (грязный, неуважительный) обходной путь (который вы также можете обернуть в пользовательский метод RenderAction ()): - По вашему мнению, сделайте это:

<%
RouteData.DataTokens.Add("GoingToRenderChildAction",
true); %> <%
Html.RenderAction("Contact", "Home");
%> <%
RouteData.DataTokens["GoingToRenderChildAction"]
= false; %>

Синтаксис бритвы:

@{
    ViewContext.RequestContext.RouteData.DataTokens.Add("GoingToRenderChildAction",
                                                         true);
}

@Html.Action("Action", "Controller" )

@{
    ViewContext.RequestContext.RouteData.DataTokens["GoingToRenderChildAction"]=false;
}

В TranslatedRoute.cs GetVirtualPath добавьте следующее в качестве первого оператора:

if(requestContext.RouteData.DataTokens.ContainsKey("GoingToRenderChildAction") &&
(bool)requestContext.RouteData.DataTokens["GoingToRenderChildAction"] == true)
{
    return base.GetVirtualPath(requestContext, values);
}

Это будет работать, но может иметь нежелательные побочные эффекты.

0 голосов
/ 22 января 2013

На ваш взгляд (синтаксис Razor, VB):

@Html.Action("Index", "Home", New With {.childAction = True})

Затем в TranslatedRoute.cs GetVirtualPath в качестве первого оператора:

if (values.ContainsKey("childAction") &&
   (bool)values["childAction"] == true)
{
  return base.GetVirtualPath(requestContext, values);
}

Этот способ намного легче и только дляжелаемое действие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...