2011-08-26 15 views
14

Attualmente, ho un filtro globale chiamato GlobalizationFilter che controlla i valori del percorso, i biscotti e le lingue del browser di intestazione per determinare le impostazioni cultura corrette per la richiesta:MVC3 globalizzazione: ha bisogno di filtro globale prima modello vincolante

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

E ' tutto funziona, ma il processo di associazione del modello sembra verificarsi prima dei filtri globali e quindi il modello di raccoglitore non tiene conto delle impostazioni della cultura.

Questo porta a problemi di interpretazione dei valori doppi, DateTime valori ecc

riuscivo a muovere il codice di rilevamento della cultura in altre posizioni, ma non mi piace nessuna delle mie opzioni:

  • Evento BeginRequest dell'applicazione. A questo punto del tempo il routing non si è verificato, quindi dovrò pescare manualmente il token di cultura /en-US/ dall'URL. Questo inaccettabile.

  • Metodo del controller Initialize(). Questo mi costringerà a scrivere una classe base per tutti i miei controller e ad ereditare i controller esistenti da esso. Non mi piace, ma opterò per questa soluzione se non emergesse nulla di meglio.

Idealmente, voglio trovare un modo per iniettare il mio codice tra il "percorso completo" e gli eventi "vincolante modello parte", ma non ho trovato nulla in MSDN/Google su questo.

O forse c'è un altro modo per gestire la globalizzazione MVC3 di cui non sono a conoscenza?

Grazie in anticipo per qualsiasi contributo.

risposta

15

Estrarre il codice che determina la cultura in un componente/classe separati. Quindi creare un ModelBinder che deriva dal DefaultModelBinder che utilizza la classe per impostare la cultura prima di chiamare 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); 
    } 
} 

e quindi registrarlo per l'applicazione (in Application_Start)

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

dal momento che ho intenzione di ottenere un legatore modello personalizzato alla fine, comunque, sembra il modo migliore. Grazie – Zruty

+0

Tuttavia, impostare la cultura a livello di richiesta in un raccoglitore modello sembra un po 'contro-intuitivo .. – Zruty

+0

è possibile memorizzare la cultura in anticipo, impostare la cultura e associare il modello e quindi ripristinare la cultura originale. Un modello di raccoglitore personalizzato è semplicemente una giunzione nell'architettura MVC, è possibile implementarlo in altri luoghi se si è a disagio con gli argomenti Principio di responsabilità singola. Ad esempio, è possibile definire il proprio gestore di route che imposta la cultura. Dipende dai tuoi principi guida. Se la testabilità è importante, non metterla da qualche parte che sarà difficile da testare (come 'Application_BeginRequest') :) –

Problemi correlati