Meilleur endroit pour définir CurrentCulture pour les applications Web ASP.NET MVC multilingues

Pour les applications Web ASP.NET MVC 3 multilingues, je détermine les éléments Thread.CurrentThread.CurrentCulture et Thread.CurrentThread.CurrentUICulture sur la fabrique de contrôleurs comme suit:

 public class MyControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { //Get the {language} parameter in the RouteData ssortingng UILanguage; if (requestContext.RouteData.Values["language"] == null) UILanguage = "tr"; else UILanguage = requestContext.RouteData.Values["language"].ToSsortingng(); //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); } } 

Le code ci-dessus a presque un an maintenant! Donc, j’ouvre pour des suggestions.

Et je l’enregistre sur le fichier Global.asax comme:

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

Cela fonctionne bien mais je ne suis pas sûr si c’est la meilleure pratique et le meilleur endroit pour faire ce type d’action.

Je ne suis pas tombé dans le rôle principal de ControllerFactory et je ne parviens pas à le comparer à ActionFilterAtsortingbute .

Que pensez-vous du meilleur endroit pour faire ce type d’action?

J’ai utilisé un ActionFilter global pour cela, mais j’ai réalisé récemment que la définition de la culture actuelle dans la méthode OnActionExecuting était trop tardive dans certains cas. Par exemple, lorsque le modèle après une requête POST parvient au contrôleur, ASP.NET MVC crée une métadonnée pour le modèle. Cela se produit avant que toute action ne soit exécutée. Par conséquent, les valeurs d’atsortingbut DisplayName et d’autres éléments d’annotations de données sont gérés à l’aide de la culture par défaut à ce stade.

Finalement, j’ai déplacé la culture actuelle vers l’implémentation personnalisée IControllerActivator et cela fonctionne comme un charme. Je suppose que c’est presque la même chose du sharepoint vue du cycle de vie des requêtes pour héberger cette logique dans la fabrique de contrôleurs personnalisés, comme c’est le cas aujourd’hui. C’est beaucoup plus fiable que l’utilisation d’ ActionFilter global.

CultureAwareControllerActivator.cs :

 public class CultureAwareControllerActivator: IControllerActivator { public IController Create(RequestContext requestContext, Type controllerType) { //Get the {language} parameter in the RouteData ssortingng language = requestContext.RouteData.Values["language"] == null ? "tr" : requestContext.RouteData.Values["language"].ToSsortingng(); //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())); } } 

Je sais qu’un anser a déjà été sélectionné. L’option que nous avons utilisée était d’initialiser la culture actuelle du thread dans l’événement OnBeginRequest pour l’application. Cela garantit que la culture est découverte à chaque demande

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

Une autre solution consiste à placer ce code dans la méthode OnActionExecuting d’un ActionFilter personnalisé, qui peut être enregistré dans la collection GlobalFilters:

http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

Au lieu de remplacer OnActionExecuting vous pouvez remplacer Initialize ici comme ceci

 protected override void Initialize(RequestContext requestContext) { ssortingng culture = null; var request = requestContext.HttpContext.Request; ssortingng 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.QuerySsortingng.AllKeys.Contains("culture")) { culture = request.QuerySsortingng["culture"]; } else { culture = cultureName; } Uitlity.CurrentUICulture = culture; base.Initialize(requestContext); }