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:
<cultures><culture code="en-us">Logitech SmartCam 124</culture></cultures>
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:
To get a Dictionary from my XML, I use this helper method:
public static Dictionary<string, string> GetDictionary(string xml)
{
if (String.IsNullOrEmpty(xml))
return new 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:
public static string 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/