ASP.NET MVC - Локализация маршрута - PullRequest
22 голосов
/ 11 ноября 2009

Я хотел бы создать локализованные URL для моего сайта. Очевидно, что они должны указывать на одни и те же действия контроллера, но я хочу, чтобы первыми значениями маршрута всегда была спецификация местоположения / языка. Возможно ли это?

http://www.website.com/en/us/controller/action

http://www.website.com/en/gb/controller/action

Я понимаю, что это можно сделать, задав {language} и {location} на каждом маршруте, но я ищу подходящее, не взломанное решение.

Ответы [ 4 ]

15 голосов
/ 11 ноября 2009

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

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

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

}

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

public ActionResult Index(string culture)
{
    ViewData["Message"] = "Welcome to ASP.NET MVC! (" + culture + ")";

    return View();
}

Вы также можете, вероятно, проанализировать URL-адрес в методе Application_BeginRequest в Global.asax и установить там культуру потоков (пример кода ниже показывает, как установить культуру, анализ, который я оставляю вам).

Если вы сделаете это, вы, вероятно, не сможете использовать методы типа RedirectToAction и HTML.ActionLink, поскольку они ничего не знают о культурах. Конечно, вы всегда можете написать свой собственный.

Недостатком использования URL-адреса для сохранения культуры является то, что если вы пропустите ссылку где-то на вашем веб-сайте или пользователь покинет веб-сайт и вернется, вы можете потерять пользовательскую культуру, и им придется установить ее заново ( не конец света, но раздражает. Возможно, хорошей стороной использования URL для хранения культуры является то, что Google будет индексировать все разные языки.

Если вас больше беспокоит пользовательский опыт или простота разработки с помощью индексации Google различных культур (в действительности зависит от того, какой тип сайта вы создаете), я бы предложил сохранить культуру в файле cookie или состоянии сеанса.

Ознакомьтесь с Как локализовать приложение ASP .Net MVC? . Принятый ответ указывает на сообщение в блоге , в котором показано, как можно локализовать приложение ASP.Net.

Если вы сохранили культуру, которую пользователь выбирает в файле cookie, состоянии сеанса или параметре запроса, а затем задали культуру потоков в методе BeginRequest в файле Global.asax. Затем выполняется локализация с использованием стандартных сборок Microsoft для локализации.

Следующий код позволит вам изменить культуру в любое время, просто добавив culture = ?? в строку запроса (MyPage? culture = es-MX). Затем он будет добавлен в файл cookie, поэтому вам не нужно добавлять его в конец каждой ссылки в вашей системе.

protected void Application_BeginRequest()
{
    var culture = Request["culture"] ?? Request.Cookies["culture"]?.Name;
    if (culture == null) culture = "en-US";
    var ci = CultureInfo.GetCultureInfo(culture);

    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;

    var cookie = new HttpCookie("culture", ci.Name);
    Response.Cookies.Add(cookie);
}
8 голосов
/ 20 апреля 2010

Кэширование вывода зависит от вариаций URL. Учитывайте это при разработке стратегии локализации. Если вы планируете использовать выходное кэширование, вставьте маркер локализации где-нибудь в URL.

6 голосов
/ 29 октября 2010

Это, кажется, гораздо лучший подход: http://blog.maartenballiauw.be/post/2010/01/26/Translating-routes-(ASPNET-MVC-and-Webforms).aspx

5 голосов
/ 27 сентября 2011

Вот блог, где описан очень простой и очень мощный способ хранения локализации в URL с использованием механизма маршрутизации http://adamyan.blogspot.com/2010/07/addition-to-aspnet-mvc-localization.html

Суть заключается в добавлении нового параметра ко всем маршрутам указанного типа

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

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

    foreach (Route r in routes)
    {
        if (!(r.RouteHandler is SingleCultureMvcRouteHandler))
        {
            r.RouteHandler = new MultiCultureMvcRouteHandler();
            r.Url = "{culture}/" + r.Url;
           //Adding default culture 
           if (r.Defaults == null)
           {
               r.Defaults = new RouteValueDictionary();
           }
           r.Defaults.Add("culture", Culture.ru.ToString());

           //Adding constraint for culture param
           if (r.Constraints == null)
           {
               r.Constraints = new RouteValueDictionary();
           }
           r.Constraints.Add("culture", new CultureConstraint(Culture.en.ToString(), 
Culture.ru.ToString()));
        }
   }

}

и действие контроллера переключения

public ActionResult ChangeCulture(Culture lang, string returnUrl)
{
     if (returnUrl.Length >= 3)
     {
         returnUrl = returnUrl.Substring(3);
     }
     return Redirect("/" + lang.ToString() + returnUrl);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...