ASP.NET MVC - Локализация маршрута
Я хотел бы создать локализованные URL для моего сайта. Очевидно, что они должны указывать на одни и те же действия контроллера, но я хочу, чтобы первыми значениями маршрута всегда была спецификация местоположения / языка. Это возможно?
http://www.website.com/
en/us
/ Контроллер / действиеhttp://www.website.com/
en/gb
/ Контроллер / действие
Я понимаю, что это может быть сделано путем определения {language}
а также {location}
на каждом маршруте, но я ищу гладкое, не хакерское решение.
4 ответа
Вы можете создать маршрут, в который встроена культура, вот так...
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);
}
Кэширование вывода зависит от вариаций URL. Учитывайте это при разработке стратегии локализации. Если вы планируете использовать кэширование вывода, вставьте маркер локализации где-то в URL.
Похоже, что это гораздо лучше: http://blog.maartenballiauw.be/post/2010/01/26/Translating-routes-(ASPNET-MVC-and-Webforms).aspx
Вот блог, где описан очень простой и очень мощный способ хранения локализации в 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);
}