Ответ 1
Вы можете посмотреть следующее руководство. Он использует сеанс для сохранения предпочтений текущего языка, но код можно легко настроить, чтобы использовать файл cookie. Идея состоит в том, что у вас будет действие контроллера:
public ActionResult ChangeCulture(string lang, string returnUrl)
{
var langCookie = new HttpCookie("lang", lang)
{
HttpOnly = true
};
Response.AppendCookie(langCookie);
return Redirect(returnUrl);
}
а затем в Global.asax
вы можете подписаться на событие Application_AcquireRequestState
, чтобы установить текущую культуру потока на основе значения файла cookie:
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
var langCookie = HttpContext.Current.Request.Cookies["lang"];
if (langCookie != null)
{
var ci = new CultureInfo(langCookie.Value);
//Checking first if there is no value in session
//and set default language
//this can happen for first user request
if (ci == null)
{
//Sets default culture to english invariant
string langName = "en";
//Try to get values from Accept lang HTTP header
if (HttpContext.Current.Request.UserLanguages != null && HttpContext.Current.Request.UserLanguages.Length != 0)
{
//Gets accepted list
langName = HttpContext.Current.Request.UserLanguages[0].Substring(0, 2);
}
langCookie = new HttpCookie("lang", langName)
{
HttpOnly = true
};
HttpContext.Current.Response.AppendCookie(langCookie);
}
//Finally setting culture for each request
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = ci;
//The line below creates issue when using default culture values for other
//cultures for ex: NumericSepratore.
//Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
}
Теперь это говорит, что использование файлов cookie и сеанса для хранения текущего языка не является дружественным к SEO. То, что я предпочитаю делать, когда мне нужно локализованное приложение, - использовать специальный маршрут, который будет содержать язык:
routes.MapRoute(
"Default",
"{lang}/{controller}/{action}/{id}",
new
{
lang = "en-US",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
а затем префикс всех моих URL-адресов. Это обеспечивает уникальные URL-адреса для разных языков, чтобы роботы могли правильно индексировать весь контент. Теперь все, что осталось, - это изменить метод Application_AcquireRequestState
так, чтобы он использовал токен lang
URL-адреса и на основании его значения задал правильные Thread.CurrentThread.CurrentUICulture
и Thread.CurrentThread.CurrentCulture
.
И теперь, когда вы захотите изменить язык, вы просто создадите правильную ссылку:
@Html.ActionLink("Page index en français", "index", new { lang = "fr-FR" })