Et oui, je suis encore en train de m'amuser avec la preview de MVC 2. A force de découvrir de nouvelles fonctionnalités qui roxent toutes plus les unes que les autres, je m'étais fait à l'idée que MVC était parfait…

Jusqu'à la nuit dernière, où j'ai fait un cauchemar : je devais gérer la localisation dans un site web, et je ne savait pas comment faire ! En effet, si ASP.NET gère très facilement la localisation sur les contrôles serveur, avec MVC on a tendance à ne pas les utiliser, et l'outil de génération des fichiers de ressources, même s'il est toujours présent, ne génère donc rien. Je me suis donc levé, ai rallumé mon ordinateur, et me suis penché sur la question.

Eh bien, je ne vais pas faire durer le suspens plus longtemps, la gestion de la localisation avec MVC n'est pas beaucoup plus compliquée qu'avant. En effet, si les fichiers de ressource ne sont pas générés automatiquement, rien ne nous empêche de les créer nous même et de les appeler dans nos pages.

J'ai donc créé un fichier Strings.resx, Strings.fr.resx et Strings.en.resx ; dans lequel j'ai mis une chaine de caractère nommée "Texte1", que j'ai traduite en anglais et en français. Dans la page aspx, pour afficher mon texte localisé, c'est tout simple :

<%= Strings.Texte1 %>

Ceci affiche donc mon texte dans la bonne langue, en fonction de la culture sélectionnée. Rien de bien compliqué, donc…

Là où je me suis un peu plus creusé la tête, c'est quand j'ai voulu donner à l'utilisateur la possibilité de changer de langue. Encore une fois, c'est pas plus compliqué qu'en ASP.NET classique. N'oublions pas que dans ASP.NET MVC, il y a ASP.NET : une ViewPage MVC est une page comme une autre !

Pour changer la culture d'une page, il suffit de changer la culture du thread courant dans la méthode InitializeCulture() de la page.

Mais comment faire ici, puisque avec MVC on n'a plus de code behind ? Eh bien, tout simplement en changeant la page de base. Dans les directives de mes pages aspx, j'ai changé ça:

<%@ Page Inherits="System.Web.Mvc.ViewPage" %> 

par :

<%@ Page Inherits="MvcTools.BasePage" %> 

Avec ma classe BasePage qui hérite de ViewPage et qui redéfinit le InitializeCulture() :

public class BasePage<T> : ViewPage<T>
{
	private String UserCulture
	{
		get
		{
			return Session["UserCulture"] as String;
		}
		set
		{
			Session["UserCulture"] = value;
		}
	}

	protected override void InitializeCUlture()
	{
		base.InitializeCUlture();

		if (String.IsNullOrEmpty(UserCulture))
			UserCUlture = "en-US";

		Thread.CurrentThread.CurrentCulture =
			new Sustem.Globalization.CultureInfo(UserCulture);
		Thread.CurrentThread.CurrentUICulture =
			new Sustem.Globalization.CultureInfo(UserCulture);
	}
}

public class BasePage : BasePage<Object>
{
}

Dans cet exemple, on vérifie au chargement de la page si la culture est sauvegardée en session, si elle n'existe pas on définit une culture par défaut ; puis on change la culture du thread courant. Il suffit de faire ça pour qu'au chargement de notre page aspx le bon fichier de ressource soit chargé.

Ensuite, pour que l'utilisateur puisse changer de ressource, c'est tout simple : on est en MVC, on crée donc une action dans notre contrôleur qui va changer la culture. Puisqu'on a défini la culture dans la Session, on y a directement accès depuis le contrôleur pour le mettre à jour :

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Localize(String lang)
{
	Session["UserCulture"] = lang;
	return RedirectToAction("Index");
}