Designing for Internationalization

Web sites and Web Applications today, are very often exposed beyond the borders of your home country, and therefore users speak different languages, and has a different currency, date- and time formats etc. ASP.NET provides you with an entire namespace for handling things like this. That is the System.Globalization namespace, where you will find a lot of classes for handling your every day globalization tasks. I’m not going to cover anything in this namespace now, if you want to get your hands dirty take a look at this video: http://asp.net/learn/videos/video-40.aspx where you will see how to use local and global resources for your application.

Using a global resource file for a place to store display text on buttons, labels, validation controls etc. is fine. But if you have an e-commerce site, selling products in multiple regions with different languages, you need an extra level. That level is a way to globalize e.g. the name and description of your product. When a user changes language, the name and description of your “display product details page” should change accordingly.

For me, the ideal solution should not result in extra database columns like name_us, name_da, name_es. This would be a very static solution, as you would have to change your database whenever a new language is added to your application. Nor should it require extra tables, so you need to join like hell, when you need to select a product.

I’ve decided to store e.g. the Name values as XML in the database, and parse that XML into a Dictionary<string, string> property on my Product object, with the key of the Dictionary being the language code (en-US for US English). To me this seems to work just fine. My database design is not getting more complex, and I can get and set values quite easily.

The XML string that goes into my ProductName column in the database table, looks like this:

Logitech SmartCam 124

On my Product object, the Name property is a Dictionary:

private Dictionary<string, string> _Name; public Dictionary<string, string> Name { get { return _Name; } set { if (_Name != value) MarkDirty("Name"); _Name = value; } }
When I need to get the US English value of the Product.Name property, I call:
p.Name["en-us"]
To get a Dictionary from my XML, I use this helper method:
publicstatic Dictionary<string, string> GetDictionary(string xml) { if (String.IsNullOrEmpty(xml)) returnnew Dictionary<string, string>(owner); XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); Dictionary<string, string> dic = new Dictionary<string, string>(); foreach (XmlNode node in doc.DocumentElement) { dic.Add(node.Attributes["code"].Value, node.InnerText); } return dic; }
And when I want to update my database, after I change the Name of the Product, I convert to Dictionary to an XML string using this helper method:
publicstaticstring GetXmlDocument(Dictionary<string, string> dic) { XmlDocument doc = new XmlDocument(); XmlNode docElement = doc.CreateNode(XmlNodeType.Element, "cultures", ""); foreach (string key in dic.Keys) { XmlNode node = doc.CreateNode(XmlNodeType.Element, "culture", ""); XmlAttribute att = doc.CreateAttribute("code"); att.Value = key; node.Attributes.Append(att); node.InnerText = dic[key]; docElement.AppendChild(node); } doc.AppendChild(docElement); return doc.OuterXml; }
If you need more information on this huge topic, take a look at the ASP.NET Wiki: [http://wiki.asp.net/page.aspx/55/internationalization/](http://wiki.asp.net/page.aspx/55/internationalization/ "http://wiki.asp.net/page.aspx/55/internationalization/")