As one would expect, ASP.NET has localization (L10n) features that help developers support internationalization (i18n) when building websites. In particular this post will focus on Implicit Localization with Web Page Resource files.
Local Resource Files
For the purposes of this post the focus will be on local resource files (there are also global resource files). If you are familiar with Java Resource Bundles, then understanding how resource files function should be fairly simple since they are very similar concepts. The idea is that you can localize text strings to resource files so you can use one page to display content that varies for different cultures (regions) and languages. Resource files are XML files (.resx extension) that contain the localized text strings for a language and optionally a culture.
One resource file needs to be created for each unique language and culture you wish to support. Additionally there should be a default resource file that is used if there was not a match found for the specified language. The default resource file is also used when resources cannot be found within a language/culture specific resource file. This allows you to create sites or pages in your default language and incrementally translate copy to other languages.
Implementation
So how do I create and use resource files?
Pages
Create a page called default.aspx. Add a control to the page, such as a Literal:
<asp:Literal Text="This is a test" runat="server" />
For a non-localized resource you could set the Text property of the Literal, but this text string can be moved to the resource file. To define a resource you should add a resourcekey to the control:
<asp:Literal meta:resourcekey="TestKey" runat="server" />
The meta:resourcekey attribute defines the key within the resource file that specifies the text string to display.
App_LocalResources
After creating a page, add a "App_LocalResources" sub folder to whatever directory contains your files. You can add multiple App_LocalResources folders to your project. This folder will contain the resource files for the pages within that particular folder.
Local Resource Files
Using Visual Studio, right click on the App_LocalResources you just created and add a resource file for the page that was just created. Name the resource file default.aspx.resx, this will be the default resource file for the page default.aspx. Open the file and add "TestKey.Text" to the Name column, this matches the resourcekey previously specified in the Literal control. Add "This is a test" to the Value column, it specifies the Text property of the Literal for the default language and culture.
Additionally you could create language and culture specific resource files by copying the default, translating the value column and renaming the file:
- default.aspx.fr.resx - this is the resource file for French language
- default.aspx.fr-ca.resx - this is the resource file for Canadian French
- default.aspx.en-ca.resx - this is the resource for Canadian English
- default.aspx.resx - this is the original resource that can be your default language
Specifying Languages (Page.UICulture)
Now that you have created localized resource files you can define a mechanism for specifying the language. The controls on the page are dependant on the page property UICulture. Designing a mechanism for switching languages is out of the scope of this post (maybe later), but the UICulture property can be set numerous ways.
It is possible to allow the .NET runtime to automatically set the language settings based on the user's browser settings. This can be accomplished by editing the globalization section of the web.config file.
<globalization uiCulture="auto" culture="auto" />
Avoiding the UICulture Master Page Trap
That is probably a good place to start, but it is usually preferable to allow the user to override the language and culture settings. One likely place to set the UICulture would be in a master page, but unfortunately the UICulture cannot be set in a master page since master pages are not derived from page, and page has the UICulture property. I find this to be a shortcoming, but there are ways to get around it, such as deriving pages from a custom base class or setting this property individually on each page. I prefer to derive my pages from a custom base class that sets the UICulture for the page.
public class LocalizedPage : System.Web.UI.Page {
protected override void OnPreInit(EventArgs e)
{
Page.UICulture = /* logic to determine language and culture */;
base.OnPreInit(e);
}
}
I think this is a simpler solution than overriding the InitializeCulture() method outlined in the MSDN example.
Summary
Hopefully this post has helped convey what it takes to get started with resource files. I encourage everyone to further their understanding of web page resource files by reading the related MSDN articles: