9

Ich möchte eine Website in verschiedenen Sprachen erstellen. Ich lese schon, dass ich eine ActionFilter schaffen könnte, aber ich habe ein litte Problem:
Ich hatte einen benutzerdefinierten Modelbinder zu schaffen, um mit Englisch und Deutsch Zahlenformate (123,456,789.1 vs. 123.456.789,1)Ändern Sie die Kultur, bevor ModelBinder verwendet wird

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); 

    } 
} 

Diese zu arbeiten ModelBinder verwendet die aktuelle Kultur, um zu entscheiden, welches Format verwendet wird. Unglücklicherweise wird der ModelBinder verwendet, bevor der ActionFilter die Kultur ändern kann. Wie kann ich die Kultur ändern vor der ModelBinder wird aktiv?

Antwort

7

Sie können ein IHttpModule implementieren und die Kultur in BeginRequest festlegen, wie in here zu sehen ist.

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; 
    } 
} 
+0

setzen! Aber ich habe eine Frage: Weißt du, warum der Code 5 Mal pro Anfrage ausgeführt wird? – Christopher

+0

Ich bekomme dieses Verhalten nicht. Können Sie eine Watch hinzufügen ((System.Web.HttpApplication) (Absender). Request.RawUrl und sehen, ob die Anfragen die gleichen sind? – barry

+2

@Christopher Der Code wird einmal pro Anfrage ausgeführt (daher der Name BeginRequest), also gibt es vielleicht eine Anfrage für die Seite und 4 weitere für Stylesheets, Bilder oder JavaScript-Dateien. Überprüfen Sie die Request.Url, die etwas Licht geben kann. –

6

ich in der Regel die CurrentCulture und CurrentUICulture durch den Umgang mit dem PreRequestHandlerExecute Ereignisse in Global.asax.cs (man könnte auch behandeln dieses Ereignis in einem IHttpModule wie von barry) eingestellt.

Der Punkt ist, dies in einem Ereignis zu tun, das stattfindet, bevor die Modellbindung stattfindet. Es gibt mehrere andere Ereignisse, die vor diesem stattfinden, die Sie verwenden könnten.

In der HttpApplication Class finden Sie Informationen über verfügbare Ereignisse und die Reihenfolge, in der sie ausgelöst werden.

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; 
     } 
    } 

Sie können es auch tun, indem Sie die OnActionExecuting Ereignisbehandlung auf Ihrem Controller (Sie wollen wahrscheinlich eine Basis-Controller erstellen und sie dort tun, dann haben alle Controller von dieser Basis-Controller erben). Es funktioniert, danke viel

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(); 
     } 
    } 
+12

-1: OnActionExecuting wird aufgerufen, nachdem der Modellbinder aufgerufen wurde. Also OnActionExecuting ist zu spät. – Rookian

4

Instanzen von IAuthorizationFilter ausgeführt werden sollen, bevor Modell zu binden, so dass Sie die benötigten Kulturen