2012-10-09 30 views
7

¿Alguien sabe cuándo tiene lugar el enlace de modelo en el ciclo de vida de la solicitud? La razón por la que pregunto es que me estoy encontrando con algunos problemas de localización.Enlace de modelo de ASP.NET MVC4

¿La vinculación del modelo ocurre antes de que se ejecute OnActionExecuting?

Actualmente establezco la referencia cultural actual en un método de filtros de acción global OnActionExecuting pero esto no se respeta al realizar el enlace de modelo. La solicitud es un POST.

Gracias de antemano.

+0

Tenía exactamente la misma configuración y pregunta, gracias por preguntar;) –

Respuesta

0

BindModel se golpea primero. ¿Tu localización puede cambiar por solicitud? Si lo hace, puede anular la carpeta de modelo predeterminada y, si es necesario, establecer su configuración regional allí. Siga el enlace a continuación en la creación de ligante modelo personalizado

ASP.NET MVC Model Binder for Generic Type

(para probar por sí mismo sólo hay que poner dos puntos de ruptura en y verá el orden)

estoy pensando que podría haber un lugar mejor para establecer la localización, pero necesitaría más información específica, y esa podría ser una pregunta diferente.

3

Le sugiero que configure la cultura en un punto muy anterior, no en el filtro de acción. En mi proyecto actual, establecí la cultura en el evento Application_AcquireRequestState en Global.asax.cs. Puedes intentar eso.

protected void Application_AcquireRequestState(Object sender, EventArgs e) 
{ 
    // set the culture 
} 
+0

Supongo que de hecho es una mejor solución. –

+0

Esta solución funciona para mí, pero ahora significa que este código se ejecuta para cada solicitud, no solo para las acciones del controlador. Cualquier imagen o archivo JS que se haya solicitado ahora está ejecutando este código, lo que puede afectar el rendimiento. –

2

me encontré con que en una aplicación MVC la mejor forma de hacerlo es utilizar un encargo routehandler y establecer la cultura en ese controlador. Esto funciona sin problemas con ModelBinders y recursos localizados en anotaciones de datos.

public class MultiCultureMvcRouteHandler : MvcRouteHandler 
{ 
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
     // get culture from route data 
     var culture = requestContext.RouteData.Values["culture"].ToString(); 
     var ci = new CultureInfo(culture); 
     Thread.CurrentThread.CurrentUICulture = ci; 
     Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); 
     return base.GetHttpHandler(requestContext); 
    } 
} 

Hay una excelente blog article by Alex Adamyan describir esta técnica.

Véase también this question & answers en SO.

0

También me encuentro con el mismo problema. Cuando el archivador modelo tiene datos no válidos, se ejecuta antes de los filtros de acción.

No me gustaron las soluciones propuestas porque jugar con el enrutamiento no era mi solución preferida. Escuchar Application_AcquireRequestState es problemático porque este evento se desencadena para todas y cada una de las solicitudes, no solo para las solicitudes que se enrutarán a los controladores MVC.

He terminado escribiendo una implementación personalizada de IControllerFactory que usa DefaultControllerFactory internamente y ejecuta el código de localización dentro del método CreateController.
Esto tampoco es ideal, espero que ayude.

public class PluggableControllerFactory : IControllerFactory { 

    private readonly IControllerFactory innerControllerFactory; 

    public PluggableControllerFactory() { 
     innerControllerFactory = new DefaultControllerFactory(); 
    } 

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) { 
     // Run your culture localization here 

     return innerControllerFactory.CreateController(requestContext, controllerName); 
    } 

    public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName) { 
     return innerControllerFactory.GetControllerSessionBehavior(requestContext, controllerName); 
    } 

    public void ReleaseController(IController controller) { 
     innerControllerFactory.ReleaseController(controller); 
    } 

    } 
} 
Cuestiones relacionadas