Как направить многоязычный URL с помощью MVC - PullRequest
20 голосов
/ 27 января 2010

Мне нужен многоязычный URL-адрес существующего контроллера. Позвольте мне объяснить больше:

У меня есть контроллер с именем «Product» и View с именем «Software»; следовательно, по умолчанию, если пользователь вводит "http://example.com/en/Product/Software",, получайте правильный контент (который действительно существует в http://example.com/Product/Software),

Однако, если другой пользователь - французский пользователь - набирает "http://example.com/fr/Produits/logiciels",, он должен выйти над контроллером и показать с правильным содержанием (то же http://example.com/Product/Software, но с французским текстом).

Примечание: я установил таблицу маршрутов с помощью "{language} / {controller} / {action} / {id}"

Любой другой недействительный URL должен отображать страницу 404.

Возможно ли это?

Ответы [ 4 ]

9 голосов
/ 07 апреля 2014

Опираясь на пост Дэна, я использую ниже для перевода названия моего контроллера и действия.

Я создал таблицу для хранения значений, которую можно и, вероятно, следует хранить в файлах ресурсов, чтобы все было вместе; однако я использовал таблицу базы данных, так как она лучше работает с процессами моей компании.

CREATE TABLE [dbo].[RoutingTranslations](
[RouteId] [int] IDENTITY(1,1) NOT NULL,
[ControllerName] [nvarchar](50) NOT NULL,
[ActionName] [nvarchar](50) NOT NULL,
[ControllerDisplayName] [nvarchar](50) NOT NULL,
[ActionDisplayName] [nvarchar](50) NOT NULL,
[LanguageCode] [varchar](10) NOT NULL)

Затем файл RouteConfig.cs был изменен на:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //Build up routing table based from the database.  
        //This will stop us from having to create shedloads of these statements each time a new language, controller or action is added
        using (GeneralEntities db = new GeneralEntities())
        {
            List<RoutingTranslation> rt = db.RoutingTranslations.ToList();
            foreach (var r in rt)
            {
                routes.MapRoute(
                    name: r.LanguageCode + r.ControllerDisplayName + r.ActionDisplayName,
                    url: r.LanguageCode + "/" + r.ControllerDisplayName + "/" + r.ActionDisplayName + "/{id}",
                    defaults: new { culture = r.LanguageCode, controller = r.ControllerName, action = r.ActionName, id = UrlParameter.Optional },
                    constraints: new { culture = r.LanguageCode }
                );
            }                
        }

        //Global catchall
        routes.MapRoute(
            name: "Default",
            url: "{culture}/{controller}/{action}/{id}",
            defaults: new {culture = CultureHelper.GetDefaultCulture(), controller = "Default", action = "Index", id = UrlParameter.Optional }
            //defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }
}

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

(Мой код интернационализации в значительной степени основан на этом великолепном сообщении в блоге. http://afana.me/post/aspnet-mvc-internationalization-part-2.aspx)

5 голосов
/ 27 января 2010

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

Тем не менее, это возможно, но для того, чтобы сделать это, вам, вероятно, придется посмотреть на создание одного маршрута на действие для каждого иностранного языка. Таким образом, для веб-сайта с 20 действиями и тремя языками (английский, французский и немецкий) вам потребуется 41 маршрут (20 французских, 20 немецких и 1 английский). Признаюсь, не самая эффективная система, но она работает так, как вы хотите.

//You'll only need one of these, which is the default.
routes.MapRoute(
  "English route",
  "en/{controller}/{action}/{id}"
  new { controller = "Home", action = "Index", language = "en" },
);

routes.MapRoute(
  "FrenchHome",
  "fr/Demarrer/Index/{id}",
  new { controller = "Home", action = "Index", language = "fr" }
);

routes.MapRoute(
  "GermanHome",
  "de/Heim/Index/{id}", //'Heim' is, I believe the correct usage of Home in German.
  new { controller = "Home", action = "Index", language = "de" }
);

//Some more routes...

routes.MapRoute(
  "FrenchSoftware",
  "fr/Produit/Logiciels/{id}",
  new { controller = "Product", action = "Software", language = "fr" }
);

routes.MapRoute(
  "GermanSoftware",
  "de/Produkt/Software/{id}", //In this instance, Software should be the same in German and English.
  new { controller = "Product", action = "Software", language = "de" }
);

//And finally, the 404 action.
routes.MapRoute(
  "Catchall",
  "{language}/{*catchall}",
  new { controller = "Home", action = "PageNotFound", language = "en" },
  new { language = "^(en|fr|de)$" }
);

//This is for the folks who didn't put a language in their url.
routes.MapRoute(
  "Catchall",
  "{*catchall}",
  new { controller = "Home", action = "PageNotFound", language = "en" }
);

В ваших действиях, например, Продукт / Программное обеспечение ...

public ActionResult Software(string language, int id)
{
  //This would go off to the DAL and get the content in whatever language you want.
  ProductModel model = ProductService.GetSoftware(language, id);

  return View(model);
}

Я бы ЛЮБИЛ , если бы кто-нибудь пришел и сказал, что есть лучший способ сделать это, потому что я согласен, что иметь URL-адрес на иностранном языке нехорошо, и учитывая, что сам Интернет движется к тому, чтобы разрешить использование нелатинских символов в URL-адресах, чем раньше мы посмотрим на решения, тем лучше.

Не только это, но я знаю, что гордые французы не любят, когда их URL-адреса веб-сайтов содержат английский. :)

2 голосов
/ 27 января 2010

У вас должно быть что-то вроде "http://mysite.com/en/Product/Software" для английского и" http://mysite.com/fr/Product/Software" для французского, что имело бы смысл.

Используйте одно и то же представление для обоих.

Удачного кодирования.

0 голосов
/ 15 сентября 2016

Я настоятельно рекомендую следующий подход для реализации мультиязычности в веб-приложении MVC 5 (и <), потому что я считаю его наиболее универсальным из тех, которые я пробовал в последние годы. </p>

Вам нужно реализовать три вещи:

  • Мультиязычный маршрут для обработки входящих URL-адресов (если вы используете MVC5 или более позднюю версию, вы можете вместо этого использовать Маршрутизация на основе атрибутов , но я все же предпочитаю используйте глобальное правило, чтобы справиться с этим).
  • Атрибут LocalizationAttribute для обработки таких многоязычных запросов.
  • Вспомогательный метод для генерации этих URL в вашем приложении (Html.ActionLink и / или Url.Action методы расширения).

См. этот ответ для получения дополнительной информации и примеров кода.

Для получения дополнительной информации и дополнительных примеров по этой теме вы также можете прочитать эту запись в блоге , которую я написал по этой теме.

...