2009-11-11 3 views
22

Je souhaite créer des URL localisées pour mon site. Ils doivent évidemment pointer vers les mêmes actions de contrôleur, mais je veux que les premières valeurs de routage soient toujours la spécification de localisation/langue. Est-ce possible?ASP.NET MVC - Route de localisation

http://www.website.com/en/us/contrôleur/action

http://www.website.com/en/gb/contrôleur/action

Je comprends qu'il peut être fait en définissant {language} et {location} dans chaque voie, mais je suis à la recherche d'un solution lisse et non-hacky.

Répondre

14

Vous pouvez créer un itinéraire qui a la culture construit en elle comme ça ...

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     "Default",            // Route name 
     "{culture}/{controller}/{action}/{id}",       // URL with parameters 
     new { culture="en-US", controller = "Home", action = "Index", id = "" } // Parameter defaults 
    ); 

} 

Vous pouvez obtenir la culture en ajoutant un paramètre de culture à toutes vos actions comme celle-ci ...

public ActionResult Index(string culture) 
{ 
    ViewData["Message"] = "Welcome to ASP.NET MVC! (" + culture + ")"; 

    return View(); 
} 

Vous pouvez également probablement analyser l'URL dans la méthode Application_BeginRequest dans Global.asax et y définir la culture des threads (l'exemple de code ci-dessous montre comment définir la culture, l'analyse que je vous laisse).

Si vous faites cela, vous ne pourrez probablement pas utiliser les méthodes de type RedirectToAction et HTML.ActionLink car ceux-ci ne connaissent rien aux cultures. Bien sûr, vous pouvez toujours écrire le vôtre. L'inconvénient de l'utilisation de l'URL pour stocker la culture est que si vous manquez un lien quelque part sur votre site Web ou que l'utilisateur quitte le site Web, puis revient, vous pourriez perdre la culture des utilisateurs et ils devront le redéfinir (pas la fin du monde, mais ennuyeux.Peut-être un bon côté de l'utilisation de l'URL pour stocker la culture est que Google va indexer toutes les différentes langues

Si vous êtes plus préoccupé par l'expérience utilisateur ou la facilité de développement sur Google indexant les différentes cultures (dépend vraiment du type de site que vous construisez), je suggérerais de stocker la culture dans un cookie ou un état de session

How to localize ASP .Net MVC application?. La réponse acceptée pointe vers un blog post qui montre comment vous pouvez localiser une application ASP.Net.

Si vous stockez la culture que l'utilisateur sélectionne dans un cookie, un état de session ou un paramètre de requête, puis définissez la culture de threads dans la méthode BeginRequest du fichier Global.asax. La localisation est ensuite effectuée à l'aide des assemblys de localisation Microsoft standard.

Le code suivant vous permettra de changer la culture à tout moment en ajoutant simplement culture = ?? à la chaîne de requête (MyPage? culture = es-MX). Il sera ensuite ajouté à un cookie afin que vous n'ayez pas besoin de l'ajouter à la fin de chaque lien de votre système.

protected void Application_BeginRequest() 
{ 
    var culture = Request["culture"] ?? Request.Cookies["culture"]?.Name; 
    if (culture == null) culture = "en-US"; 
    var ci = CultureInfo.GetCultureInfo(culture); 

    Thread.CurrentThread.CurrentCulture = ci; 
    Thread.CurrentThread.CurrentUICulture = ci; 

    var cookie = new HttpCookie("culture", ci.Name); 
    Response.Cookies.Add(cookie); 
} 
+0

Il demande pour un moyen d'ajouter de la culture et de la langue dans toutes les routes. –

+0

Je l'ai compris. Ce que j'ai suggéré était un moyen de le faire sans l'ajouter aux routes. L'ajouter aux routes complique inutilement l'application. – Brian

+0

S'il y avait une réponse à ma question, pourriez-vous préciser ce qui pourrait compliquer la situation? – Ropstah

8

La mise en cache de sortie repose sur des variations d'URL. Considérez ceci lors de la conception de votre stratégie de localisation. Si vous envisagez d'utiliser la mise en cache de sortie, intégrez le jeton de localisation quelque part dans l'URL.

+0

Bon point, merci! – Ropstah

5

Voici un blog où décrit manière très simple et très puissant de stocker la localisation dans l'URL en utilisant le mécanisme de routage. http://adamyan.blogspot.com/2010/07/addition-to-aspnet-mvc-localization.html

le noyau est d'ajouter un nouveau paramètre à tous les circuits de type spécifié

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
    ); 

    foreach (Route r in routes) 
    { 
     if (!(r.RouteHandler is SingleCultureMvcRouteHandler)) 
     { 
      r.RouteHandler = new MultiCultureMvcRouteHandler(); 
      r.Url = "{culture}/" + r.Url; 
      //Adding default culture 
      if (r.Defaults == null) 
      { 
       r.Defaults = new RouteValueDictionary(); 
      } 
      r.Defaults.Add("culture", Culture.ru.ToString()); 

      //Adding constraint for culture param 
      if (r.Constraints == null) 
      { 
       r.Constraints = new RouteValueDictionary(); 
      } 
      r.Constraints.Add("culture", new CultureConstraint(Culture.en.ToString(), 
Culture.ru.ToString())); 
     } 
    } 

} 

et l'action du contrôleur de commutation

public ActionResult ChangeCulture(Culture lang, string returnUrl) 
{ 
    if (returnUrl.Length >= 3) 
    { 
     returnUrl = returnUrl.Substring(3); 
    } 
    return Redirect("/" + lang.ToString() + returnUrl); 
}