Изменить культуру перед использованием ModelBinder
Я хочу создать сайт на разных языках. Я уже читал, что могу создать ActionFilter, но у меня есть небольшая проблема:
Мне пришлось создать собственный ModelBinder для работы с английскими и немецкими форматами чисел (123,456,789.1
против 123.456.789,1
)
public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string key = bindingContext.ModelName;
var v = ((string[])bindingContext.ValueProvider.GetValue(key).RawValue)[0];
float outPut;
if (float.TryParse(v, NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out outPut))
return outPut;
return base.BindModel(controllerContext, bindingContext);
}
}
Этот ModelBinder использует текущую культуру, чтобы решить, какой формат используется. Но, к сожалению, ModelBinder используется до того, как ActionFilter может изменить культуру.
Как я могу изменить культуру до того, как ModelBinder станет активным?
3 ответа
Вы можете реализовать IHttpModule и установить культуру в BeginRequest, как показано здесь.
void context_BeginRequest(object sender, EventArgs e)
{
// eat the cookie (if any) and set the culture
if (HttpContext.Current.Request.Cookies["lang"] != null)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies["lang"];
string lang = cookie.Value;
var culture = new System.Globalization.CultureInfo(lang);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
Я обычно устанавливаю CurrentCulture
а также CurrentUICulture
обрабатывая PreRequestHandlerExecute
событие в Global.asax.cs
(вы также можете обработать это событие в IHttpModule
как предположил Барри).
Смысл заключается в том, чтобы сделать это в событии, которое происходит до привязки модели. Есть несколько других событий, которые происходят перед этим, которые вы могли бы использовать.
Посмотрите на класс HttpApplication для получения информации о доступных событиях и порядке их возникновения.
public class MvcApplication : HttpApplication
{
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
var culture = new CultureInfo("en-GB"); // Get the culture name from the route values / request querystring / form / cookie
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
Вы также можете сделать это, обрабатывая OnActionExecuting
событие на вашем Controller
(вы, вероятно, хотите создать базовый контроллер и сделать это там, затем все ваши контроллеры наследуются от этого базового контроллера).
public class MyBaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var culture = new CultureInfo("en-GB"); // Get the culture name from the route values / request querystring / form / cookie
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
base.OnActionExecuting(filterContext);
}
}
public class MyController : MyBaseController
{
public ActionResult Index()
{
return View();
}
}
Экземпляры IAuthorizationFilter
выполняется перед привязкой модели, что позволяет вам установить необходимые культуры