Globalização de Sítios Web Usando O Roteamento Do ASP.NET
Para quem não sabe, eu tenho um sítio web (http://PauloMorgado.NET/) que uso como presença (além dos meus blogues) na web e para testes.
Porque costumo escrever tanto em Português como em Inglês, queria que o sítio tivesse uma versão Portuguesa e uma versão Inglesa. Isto é simples de fazer usando a infra-estrutura de Globalização e Localização ASP.NET.
Mas eu queria mais do que apenas adivinhar a língua do utilizador através da linguagem do browser. Queria algo como os sítios da MSDN e TechNet onde cultura está embebida no URL o que possibilita ao utilizador escolher em que linguagem deseja ver o sítio.
Com o lançamento do ASP.NET Routing, isto é tão simples como escrever um route handler que define a cultura do pedido HTTP e devolve o page handler da página pretendida.
Algo como isto:
public class GlobalizationRouteHandler : global::System.Web.Routing.IRouteHandler
{
System.Globalization.CultureInfo culture;
System.Globalization.CultureInfo uiCulture;
public GlobalizationRouteHandler(System.Globalization.CultureInfo culture)
: this(culture, culture)
{
}
public GlobalizationRouteHandler(CultureInfo culture, CultureInfo uiCulture)
{
if (culture == null)
{
throw new ArgumentNullException("cultureInfo", "cultureInfo is null.");
}
if (uiCulture == null)
{
throw new ArgumentNullException("uiCulture", "uiCulture is null.");
}
this.culture = culture;
this.uiCulture = uiCulture;
}
private GlobalizationRouteHandler()
{
}
#region IRouteHandler Members
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
Thread.CurrentThread.CurrentCulture = this.culture;
Thread.CurrentThread.CurrentUICulture = this.uiCulture;
string path = "~/" + (requestContext.RouteData.Values["path"] as string);
var physicalPath = requestContext.HttpContext.Server.MapPath(path);
if (System.IO.Directory.Exists(physicalPath))
{
path = VirtualPathUtility.Combine(path, "Default.aspx");
}
var httpHandler = BuildManager.CreateInstanceFromVirtualPath(path, typeof(IHttpHandler)) as IHttpHandler;
return httpHandler;
}
#endregion
}
Depois é só registar as rotas para as culturas pretendidas:
routes.Add("en", new Route("en/{*path}", new GlobalizationRouteHandler(CultureInfo.GetCultureInfo("en-US"))));
routes.Add("pt", new Route("pt/{*path}", new GlobalizationRouteHandler(CultureInfo.GetCultureInfo("pt-PT"))));