vista que net mvc modelo libro introducción gratis form español desarrollo cursos curso controlador con asp asp.net-mvc asp.net-mvc-3 action-filter controller-factory

asp.net-mvc - net - que es mvc 5



El mejor lugar para establecer CurrentCulture para aplicaciones web multilingües ASP.NET MVC (4)

Para la aplicación web multilingüe ASP.NET MVC 3, estoy determinando Thread.CurrentThread.CurrentCulture y Thread.CurrentThread.CurrentUICulture en la fábrica del controlador de la siguiente manera:

public class MyControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { //Get the {language} parameter in the RouteData string UILanguage; if (requestContext.RouteData.Values["language"] == null) UILanguage = "tr"; else UILanguage = requestContext.RouteData.Values["language"].ToString(); //Get the culture info of the language code CultureInfo culture = CultureInfo.CreateSpecificCulture(UILanguage); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; return base.GetControllerInstance(requestContext, controllerType); } }

¡El código anterior tiene casi un año ahora! Entonces, abro para sugerencias.

Y registro esto en el archivo Global.asax como:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

Esto está funcionando bien, pero no estoy seguro de si es la mejor práctica y el mejor lugar para realizar este tipo de acciones.

No he profundizado en la función principal de ControllerFactory y no puedo compararla con ActionFilterAttribute .

¿Qué opinas sobre el mejor lugar para realizar este tipo de acciones?


En lugar de anular OnActionExecuting , puede anular Initialize aquí como este

protected override void Initialize(RequestContext requestContext) { string culture = null; var request = requestContext.HttpContext.Request; string cultureName = null; // Attempt to read the culture cookie from Request HttpCookie cultureCookie = request.Cookies["_culture"]; if (cultureCookie != null) cultureName = cultureCookie.Value; else cultureName = request.UserLanguages[0]; // obtain it from HTTP header AcceptLanguages // Validate culture name cultureName = CultureHelper.GetValidCulture(cultureName); // This is safe if (request.QueryString.AllKeys.Contains("culture")) { culture = request.QueryString["culture"]; } else { culture = cultureName; } Uitlity.CurrentUICulture = culture; base.Initialize(requestContext); }


Sé que un anser ya ha sido seleccionado. La opción que utilizamos fue simplemente Inicializar el cultivo actual de subprocesos en el evento OnBeginRequest para la Aplicación. Esto asegura que la cultura se descubra con cada solicitud

public void OnBeginRequest(object sender, EventArgs e) { var culture = YourMethodForDiscoveringCulutreUsingCookie(); System.Threading.Thread.CurrentThread.CurrentCulture = culture; System.Threading.Thread.CurrentThread.CurrentUICulture = culture; }



ActionFilter un ActionFilter global para esto, pero recientemente me di cuenta de que la configuración de la cultura actual en el método OnActionExecuting es demasiado tarde en algunos casos. Por ejemplo, cuando el modelo después de la solicitud POST llega al controlador, ASP.NET MVC crea un metadato para el modelo. Ocurre antes de que se ejecuten las acciones. Como resultado, los valores de los atributos DisplayName y otras cosas de anotaciones de datos se manejan usando la cultura predeterminada en este momento.

Eventualmente me mudé configurando la cultura actual en la implementación personalizada IControllerActivator , y funciona como un encanto. Supongo que es casi lo mismo desde la perspectiva del ciclo de vida de la solicitud alojar esta lógica en la fábrica de controladores personalizados, como lo hace hoy. Es mucho más confiable que el uso de ActionFilter global.

CultureAwareControllerActivator.cs :

public class CultureAwareControllerActivator: IControllerActivator { public IController Create(RequestContext requestContext, Type controllerType) { //Get the {language} parameter in the RouteData string language = requestContext.RouteData.Values["language"] == null ? "tr" : requestContext.RouteData.Values["language"].ToString(); //Get the culture info of the language code CultureInfo culture = CultureInfo.GetCultureInfo(language); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; return DependencyResolver.Current.GetService(controllerType) as IController; } }

Global.asax.cs :

public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { ... ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new CultureAwareControllerActivator())); } }