2010-11-07 29 views
4

J'utilise les moteurs de vue spark, asp.net mvc et .resx.Globalisation Spark avec ASP.NET MVC

Je veux définir une langue à travers mon habitude SessionModel (session) qui est enregistré par Castle.Windsor et a une propriété de chaîne de la culture qui peut être réglé par l'utilisateur ...

J'ai besoin du courant langue à persister sur chaque vue, sans avoir à constamment définir l'UICulture actuelle.

ne pas avoir à le faire à chaque fois dans chaque action du contrôleur:

public SessionModel SessionModel { get; set; } 

    public ActionResult Index() 
    { 
     Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(SessionModel.Culture); 
     Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; 
    } 

Le problème avec cette façon de faire, est de savoir si je vais sur une autre page la culture actuelle retourner en arrière à la langue par défaut.

Sur la vue étincelle que j'appelle simplement, pour obtenir la culture actuelle:

${SR.Home} 

SR.resx contient une entrée publique pour la maison.

Est-ce que quelqu'un a une bonne idée de comment faire ceci, devrais-je le faire avec un ActionFilter? Filtre

+0

duplication possible de [Comment localiser l'application ASP.NET MVC + Spark?] (Http://stackoverflow.com/questions/788635/how-to-localize-asp-net-mvc-spark-application) – bzlm

+0

exemple dont il parle est exactement ce qui a le problème, il persiste l'information dans une session ASP.NET ordinaire, et doit le demander sur chaque contrôleur supplémentaire. – Andrew

Répondre

1

d'action semble être une bonne idée:

public class SetCultureActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     CultureInfo culture = FetchCultureFromContext(filterContext); 
     Thread.CurrentThread.CurrentCulture = culture; 
     Thread.CurrentThread.CurrentUICulture = culture; 
     base.OnActionExecuting(filterContext); 
    } 

    private CultureInfo FetchCultureFromContext(ActionExecutingContext filterContext) 
    { 
     throw new NotImplementedException(); 
    } 
} 

puis décorez votre contrôleur de base avec cet attribut.

+0

J'ai joué avec quelque chose comme ça, et le problème est que je ne peux pas injecter la session de Windsor, j'ai dans IActionFilter. Ce qui pose alors le problème de savoir comment garder ma langue à jour ... Pour le moment, la seule façon de faire est d'utiliser le HTTPContext.Currrent.Session, ce qui est vraiment ennuyeux. Cependant, peut-être que je regarde mal, quelles sont vos idées sur FetchCultureFromContext? – Andrew

+0

Oui, vous ne pouvez pas utiliser DI hors de la boîte. Il existe [solutions de contournement] (http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/05/03/dependency-injection-in-asp-net-mvc-filters.aspx). Cela [sera possible] (http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html) bien que dans ASP.NET MVC 3. –

+0

J'ai fini par utiliser: http://weblogs.asp.net/psteele/archive/2009/11/04/using-windsor-to-inject-dependencies-into-asp-net-mvc-actionfilters.aspx en injectant ma session dans un ActionFilterAttribute personnalisé, et cela a fonctionné. Merci de votre aide. – Andrew

0

Il existe une solution bien meilleure et évolutive (d'un point de vue de la flexibilité) à ce problème qui a été résolu si vous utilisez Spark View Engine. Jetez un oeil à la sample solution here in the code base pour un excellent exemple de la façon de faire de l'internationalisation ou de la mondialisation avec Spark. Il n'y a absolument pas besoin de commencer à faire des choses fantaisistes avec vos ActionFilters - et cette méthode fonctionne dans MVC2 et MVC3 pour permettre une migration facile si c'est votre plan futur.

Mise à jour

En réponse à votre autre question concernant l'échantillon dans la base de code Spark Je pense qu'il ya quelques façons de dépecer ce chat. Une façon serait de garder la culture dans le cadre de la session, mais dans les projets précédents où nous ne voulions pas cela, nous avons fait ce que font déjà beaucoup de sites web - nous avons inclus la culture comme paramètre dans les données de route en nous assurant inclus dans l'URL:

routes.Add(new Route("{culture}/{controller}/{action}/{id}", new MvcRouteHandler()) 
    { 
     Defaults = new RouteValueDictionary(
     new { culture="en-us" action="Index", id="" }), 
    }); 

Ce genre de chose en combinaison avec le module Spark je l'ai mentionné ci-dessus vous donne la liberté de passer tout le temps se concentrer sur vos fichiers .resx au lieu de tout votre temps à trouver la culture et de routage manuellement. Le fait que vous ayez un Index.spark et un Index.fr.spark dans le même dossier de vues signifie que le reste sera pris en charge pour vous.

Espérons que ça aide!
Tous les meilleurs,
Rob

+0

voir, la réponse ci-dessous, était de beaucoup à entrer dans cette petite boîte. – Andrew

+0

J'ai ajouté une mise à jour à ma réponse. J'espère que je l'ai couvert? – RobertTheGrey

0

Je suppose que je me manque quelque chose. C'est ce que j'essaie d'éviter (Application.cs) à l'intérieur des échantillons d'allumage, j'ai déjà une session personnalisée, il n'a pas besoin de gérer une autre, juste pour la « culture »:

l'exemple de code:

public static string GetSessionCulture(ControllerContext controllerContext) 
    { 
     return Convert.ToString(controllerContext.HttpContext.Session["culture"]); 
    } 

    public static void SetSessionCulture(ControllerContext controllerContext, string culture) 
    { 
     controllerContext.HttpContext.Session["culture"] = culture; 
    } 

également après son fait, comment puis-je charger la culture actuelle pour chaque page que j'ai, je dois faire appel à l'intérieur de HomeController Index pour tirer la culture actuelle de la session:

public object Index() 
    { 
     var user = new UserInfo 
           { 
            Name = "Frankie", 
            Culture = Application.GetSessionCulture(ControllerContext) 
           }; 

     try 
     { 
      Thread.CurrentThread.CurrentCulture = 
       CultureInfo.CreateSpecificCulture(user.Culture); 
     } 
     catch 
     { 
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); 
     } 
     Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; 

     ViewData["user"] = user; 
     return View(); 
    } 

qui la seule façon que je peux venir avec En ce moment, soit en créant un ActionFilter personnalisé ou en créant un contrôleur de base.