2009-07-31

Simple ASP.NET Localization

I've seen a lot of solutions for localization in ASP.NET -- many of which use a database to store the localized content. The problem with this approach is that you have to recreate the tools that you are already using. Specifically: text editors (now you need an admin site to update the database content), source control (now you need revision history), content uploading (now you need an SSIS or custom Windows Service to deploy content). It's a bigger project than you want.

Generally, whenever HTML goes into a database (apart from a Forum), I question the need. The reason being that HTML is code and code belongs in Source Control. If Developers are the only ones updating the content (we're not talking about CMSs here) then why force them to use tools they aren't familiar with to do the same job they do all day long?

A solution that I've found that works well is to use an HTTP Module and a Localized directory of files. First, let's go over the HTTP Module.


///
/// Rewrites URLs to Custom Pages if they exist
///

public class LocalizationModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.BeginRequest += OnBeginRequest;
}

private void OnBeginRequest(object src, EventArgs e)
{
// Replace the below with a way to determine culture however you'd like
string culture = SomeService.GetCulture();
if (String.IsNullOrEmpty(culture)) return;

HttpApplication app = src as HttpApplication;
if (app == null) return;

string fullPath = app.Request.Path;
string possiblePath = app.Context.Server.MapPath("/" + ConfigurationManager.AppSettings["LocalizationDirectory"]) + "\\" + culture + fullPath.Replace("/", "\\");

if (File.Exists(possiblePath.ToLower()))
{
string virtualPath = "/" + ConfigurationManager.AppSettings["LocalizationDirectory"] + "/" + culture + fullPath;

app.Context.RewritePath(virtualPath);
}

}

public void Dispose()
{

}
}


The "SomeService.GetCulture()" can be anything. I've made GetCulture return the culture code using Cookies (with a value of say "fr-FR"), the URL (i.e. "http://www.somesite.com/en-US/page.aspx") or even based on a drop down selection.

The content of your site can live within a specified folder, see:

Localization Module Example

The HTTP module will then serve up the corresponding page in the localization directory.

Pretty simple stuff. It's a LOT easier to manage than some database localization solutions. I highly recommend using flat files for content that is only going to be touched by developers -- after all -- we're used to it.

No comments: