2011-08-26 17 views
14

Actualmente, tengo un filtro global llamado GlobalizationFilter que comprueba los valores de ruta, las galletas y los idiomas del navegador de cabecera para determinar la configuración cultura correctos para el modelo de solicitud:MVC3 globalización: necesita filtro global antes del enlace

public override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    // determine cultureInfo 
    Thread.CurrentThread.CurrentCulture = cultureInfo; 
    Thread.CurrentThread.CurrentUICulture = cultureInfo; 
} 

Se todos funcionan, pero el proceso de vinculación del modelo parece ocurrir antes de los filtros globales, por lo que el archivador modelo no tiene en cuenta la configuración cultural.

Esto lleva a problemas para interpretar los valores dobles, etc. DateTime valores

pude mover el código de detección de la cultura a otros lugares, pero no me gusta ninguno de mis opciones:

  • Evento de aplicación BeginRequest. En este momento, el enrutamiento no se ha realizado, por lo que tendré que pescar manualmente el token de cultura /en-US/ de la URL. Esto es inaceptable.

  • método del controlador Initialize(). Esto me obligará a escribir una clase base para todos mis controladores y heredar los controladores existentes de ella. No me gusta esto, pero optaré por esta solución si no sale nada mejor.

Idealmente, quiero encontrar la manera de inyectar el código entre la "ruta completa" y "eventos vinculante modelo comienza", pero no he encontrado nada en MSDN/Google en esto.

O tal vez hay alguna otra manera de manejar la globalización MVC3 que soy consciente de?

Gracias de antemano por cualquier contribución.

Respuesta

15

Extraer el código que determina la cultura en un componente/clase separada. A continuación, crear una ModelBinder que se deriva de DefaultModelBinder que utiliza la clase para establecer la cultura antes de llamar BindModel

public class CultureAwareModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     /* code that determines the culture */ 
     var cultureInfo = CultureHelper.GetCulture(controllerContext.HttpContext); 

     //set current thread culture 
     Thread.CurrentThread.CurrentCulture = cultureInfo; 
     Thread.CurrentThread.CurrentUICulture = cultureInfo; 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

y luego registrarlo para la aplicación (en Application_Start)

// register our own model binder as the default 
ModelBinders.Binders.DefaultBinder = new CultureAwareModelBinder(); 
+0

ya que voy a conseguir una carpeta de modelo personalizado eventualmente de todos modos, parece la mejor manera. Gracias – Zruty

+0

Sin embargo, establecer la cultura de toda la solicitud en una carpeta de modelo parece un poco contra-intuitiva. – Zruty

+0

puede almacenar la cultura de antemano, establecer la cultura y vincular el modelo y luego restaurar la cultura original. Un encuadernador de modelo personalizado es simplemente una costura en la arquitectura MVC, puede implementarlo en otros lugares si no se siente cómodo con los argumentos del Principio de responsabilidad único. Por ejemplo, puede definir su propio controlador de ruta que establece la cultura. Depende de sus principios de conducción. Si la capacidad de prueba es importante, no la coloque en un lugar que sea difícil de probar (como 'Application_BeginRequest') :) –

Cuestiones relacionadas