Asp.net-Mvc

在使用 ModelBinder 之前更改文化

  • January 15, 2015

我想創建一個不同語言的網站。我已經讀到我可以創建一個ActionFilter,但我有一個小問題:

我必須創建一個自定義 ModelBinder 才能使用英語和德語數字格式(123,456,789.1vs. 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 啟動之前更改文化?

您可以實現 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;
   }
}

我通常通過處理事件來設置CurrentCultureand (你也可以按照 barry 的建議處理這個事件)。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();
       }
   }

引用自:https://stackoverflow.com/questions/13445278