For those who don't know, I have this web site http://PauloMorgado.NET/ that I use both as a web presence besides my blogs and a playfield.
Because I write both in English and Portuguese, I wanted the web site to have both English and Portuguese versions. This is easily accomplished by using ASP.NET Globalization and Localization.
But I wanted to do more than guessing the user’s language form her/his web browser languages. I wanted something like the MSDN and TechNet web sites have where the culture is embedded in the URL which makes it easy for the user to choose in which language she/he wants to see the web site.
With the release of the ASP.NET Routing, this is as easy as writing a custom route handler that sets the culture for the request and returns the requested page handler.
Something like this:
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
}
And now it’s only a matter of registering the handled cultures:
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"))));