Monday, August 18, 2008

ASP.NET Localization

There are a lot of articles talking about ASP.NET localization. This article is not going to give you an in-depth look of ASP.NET localization. Instead, it gives you a quick reference about localization of the commonly used content on an ASP.NET page including ASP.NET server control, HTML content, SiteMap and other resources.

To download sample application, please go to CodeProject

How to localize ASP.NET server control?

ASP.NET server control localization is the easiest of all. Once you added it to your page, you can simply switch your page to “Design” mode and then go to menu “Tools”->”Generate Local Resource”.

clip_image002

It will generate resource string for each ASP.NET server control on that page. In this example, a file with name Default.aspx.resx was created. It contains all the resource name/value pair for our Default.aspx page.

clip_image004      clip_image005

Switch back to source pane, you will see it added some code like the following in your HTML.       

<asp:Button ID="Button1" runat="server" Text="Hello" meta:resourcekey="Button1Resource1" />





You then can copy/paste to create resource file for other culture. For example, you may create Default.aspx.fr.resx for French user.



clip_image007  clip_image008



The following screen shot is when the language is set to English in Internet Explorer.



clip_image010



Change the language to French by going to Internet Explorer->Tools->Internet Options->Languages



clip_image012



Here is the French version page



clip_image014









How to localize HTML content?



To localize the regular HTML content, you can use <asp:Localize> control. Let’s use an example to explain it.



You have a header and a paragraph in your page.





<h1>Localization Page Header</h1>
<p>This is a demo page to show you how to do localization in ASP.NET</p>









 





To localize it, you need to add <asp:Localize> to them.




<h1><asp:Localize ID="Header" runat="server">Localization Page Header</asp:Localize></h1>
<p><asp:Localize ID="Localize1" runat="server">This is a demo page to show you how to do localization in ASP.NET</asp:Localize></p>







 





Then you may manually create a resource file and add meta:resourcekey="HeaderResource1” to your page. Or you can take advantage of Visual Studio to automatically generate it. Switch your page to “Design” mode. Go to menu “Tools”->”Generate Local Resource”.



 It will generate the following code and the resource file (i.e. yourfile.aspx.resx) for you.



Here is the code it changed:



 







<h1><asp:Localize ID="Header" runat="server" meta:resourcekey="HeaderResource1" Text="Localization Page Header"></asp:Localize></h1>
<p><asp:Localize ID="Localize1" runat="server" meta:resourcekey="Localize1Resource1" Text="This is a demo page to show you how to do localization in ASP.NET"></asp:Localize></p>







The rest steps are as same as how would you localize ASP.NET server control.








 





How to localize site map?



 This article will give you more detail on SiteMap localization.



1.       Enable site map localization by adding enableLocalization="true" to site map file, for example: Web.sitemap file




<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">



2.       Change the value of the property that you want to localize to a resource string in siteMapNode using this format “$resources:ClassName,KeyName,DefaultValue”




<siteMapNode url="Default.aspx" title="$resources:SiteMapLocalizations,HomePageTitle" description="$resources:SiteMapLocalizations,HomePageDescription">



 



3.       Add global resource folder and files. Right click the web site in solution explorer. Click on “Add ASP.NET folder”. Click on “Add App_GlobalResources” from the sub-menu. It will add an “App_GlobalResources” folder to your root directory.



clip_image016



Then add resource file, for example, SiteMapLocalizations.resx. In the file, you will have name/value pair for each of the resource string. For example, 



Name                                    Value



HomePageTitle                 Home





 





4.       Create resource file for each culture you may have. For example, you may have a file called SiteMapLocalizations.fr.resx for French.



Below are the screen shot of menus in English and French



   clip_image018




How to localize string programmatically?



Sometimes you may need to display a string, for example, an error message at the run time. You will need to localize it programmatically. Here is how to do it:



1.       Add resource file under App_GlobalResources folder. In this example, we added a file called “CommonResource.resx” and a French version “CommonResource.fr.resx”



clip_image020   clip_image021



2.       Add the following code to use that resource file




ResourceManager rm = new ResourceManager("Resources.CommonResource", Assembly.Load("App_Glob alResources"));
this.Label1.Text = rm.GetString("HelloString");



 


After posting this on CodeProject, I received a comment from Alexander Nesterenko indicating there are better ways to get the resource string. Here is his comment:



You should get resources from ~\App_GlobalResources\MyMessages.resx by:

1. Generated code wrapper - string message = Resources.MyMessages.Hello;


2. Resource expression - <asp:Label Text="<%$ Resources: MyMessages, Hello %>" />


3. Method GetGlobalResourceObject - string message = GetGlobalResourceObject("MyMessages", "Hello");


You should get resources from ~\App_LocalResources\default.aspx.resx by:


1. Resource expression - <asp:Label Text="<%$ Resources: Hello %>" />


2. meta:resourceKey - <asp:Label meta:resourceKey="labelResourceKey" />


3. Method GetLocalResourceObject - string message = GetLocalResourceObject("Hello");




Thanks, Alexander.




Here are the screen shots:


clip_image023





 






How to dynamically change culture?



In the sample code, we added two LinkButtons. When you click on “English”, the page will switch to English culture; click on “Français”, it will switch to French. To detect which link button is clicked, we used the Request.Form[“__EventTarget”]. It works, but probably not the best way.



We override the “InitializeCulture” method of the page, so it will display the correct culture based on the selection we made.



HTML code:




<asp:LinkButton ID="LanguageEnglish" Text="English" runat="server"></asp:LinkButton>
<asp:LinkButton ID="LanguageFrench" Text="Français" runat="server"></asp:LinkButton>





ASP.NET code




protected override void InitializeCulture()
{
string language = Request.Form["__EventTarget"];
string languageId = "";

if (!string.IsNullOrEmpty(language))
{
if (language.EndsWith("French")) languageId = "fr-FR";
else languageId = "en-US";
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(languageId);

Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageId);
}
base.InitializeCulture();
}





clip_image025






This works for everything except the menu. If you have a menu using SiteMap in your page. You may need to call menu.DataBind() in Page_Load event or set EnableViewState to false. Otherwise your menu will still show the previous culture string while other content change to the new culture.



When we dynamically change the culture, most likely we need to store it somewhere so it won’t get lost when we jump from page to page. In the sample application, we used Session to do that.



Happy Programming!

No comments:

Post a Comment