Изменить культуру на основе ссылки MVC4
У меня есть любопытство, связанное с изменением культуры в MVC. Я попытался двумя способами, но, видимо, я где-то ошибся.
В моем Web.config у меня есть:
<globalization uiCulture="auto" culture="auto" />
Вот как я попытался изменить культуру потока:
<li>@Html.ActionLink("Eng", "ChangeCulture", "Home", new { lang="en-US"}, new { @class = "languageSelectorEnglish" })</li>
Первый метод
У меня есть следующий контроллер:
public void ChangeCulture(string lang)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
Response.Cookies.Remove("Language");
var langCookie = new HttpCookie("Language");
langCookie["Language"] = lang;
langCookie.Value = lang;
langCookie.Expires = System.DateTime.Now.AddDays(21);
Response.Cookies.Add(langCookie);
Response.Redirect(Request.UrlReferrer.ToString());
}
Второй метод
public ActionResult ChangeCulture(string lang)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
// Split the url to url + query string
var fullUrl= Request.UrlReferrer.ToString();
var questionMarkIndex = fullUrl.IndexOf('?');
string queryString = null;
string url = fullUrl;
if (questionMarkIndex != -1) // There is a QueryString
{
url = fullUrl.Substring(0, questionMarkIndex);
queryString = fullUrl.Substring(questionMarkIndex + 1);
}
// Arranges
var request = new HttpRequest(null, url, queryString);
var response = new HttpResponse(new StringWriter());
var httpContext = new HttpContext(request, response);
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
// Extract the data
var values = routeData.Values;
var controllerName = values["controller"];
var actionName = values["action"];
var areaName = values["area"];
return RedirectToAction(actionName.ToString());
}
Где я ошибаюсь? Спасибо.
Ответы
Ответ 1
Кажется, мне нужно переопределить culture
для моего resource strings
, а не thread
. Итак, мой последний метод:
public void ChangeCulture(string lang)
{
Resources.Resources.Culture = new CultureInfo(lang);
Response.Redirect(Request.UrlReferrer.ToString());
}
Надеюсь, это поможет.
ОБНОВЛЕНИЕ:
Недопустимый код, когда ваше приложение используется несколькими пользователями, поскольку оно устанавливает одинаковую культуру для каждого пользователя, независимо от того, какой браузер он использует.
Хороший способ сделать это - создать метод, который устанавливает cookie
в вашем браузере:
public void ChangeCulture(string lang)
{
Response.Cookies.Remove("Language");
HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["Language"];
if (languageCookie == null) languageCookie = new HttpCookie("Language");
languageCookie.Value = lang;
languageCookie.Expires = DateTime.Now.AddDays(10);
Response.SetCookie(languageCookie);
Response.Redirect(Request.UrlReferrer.ToString());
}
После этого (сложный путь) вам нужно сделать каждый контроллер наследуемым от одного BaseController. Это сложно, потому что вам нужно переопределить Initialize
.
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["Language"];
if (languageCookie != null)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(languageCookie.Value);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageCookie.Value);
}
else
{
//other code here
}
base.Initialize(requestContext);
}
Ответ 2
Удалите строку в файле web.config:
<globalization uiCulture="auto" culture="auto" />
При установке этих параметров по умолчанию по умолчанию используется язык для языка пользователя, установленного в браузере. Это переопределяет настройку Thread.