Friday, 9 January 2009

Localization in Asp.Net

Since I changed to English for this blog I realised that I had to change the language of the single webpage of www.invitationaltour.com.

So I took the chance of developing a “proof-of-concept” for localization, which actually was harder than I thought when you are using master pages in asp.net. Before I started I was sure it was only a matter of setting the currentuiculture of the current thread, since the page class has a property named Culture which can be set to change the culture for a page, but it was more to it than that. I did a simplified version of localization, and in the future I will make a more appropriate solution and will write a post about that solution. For now I just wanted to localize a single page, which are nested in a master page. The correct language should be determined by the browsers language settings. So, here it is.
First, I use the Localization control. You can use a literal control, they are exact the same, but the localisation control allows you to edit the text in design mode.

<h1>
    <asp:Localize 
    ID="Header1" 
    meta:resourceKey="Header1" 
    runat="server" 
    Text="Välkommen!"/>
</h1>

Välkommen is Swedish for Welcome, and Swedish is the default language for the site. This is the first word on the page at www.invitationaltour.com

Next I created a folder under my solution and named it App_LocalResources. Resource files under App_LocalResources are page specific, and resources in the folder App_GlobalResources  are application specific, and should be the place to store words that are used through out the application.

Next, I added a resource file to the App_LocalResources and named the file to Default.aspx.resx. Double click on that file and an editor i shown where you can add and edit localised words. This file has no culture info in it, so the words in this file will be the default language for the page.

Add a new item by typing Header1.Text in the name column, and the value for the text in the Value column. As you can see in my asp.net code, I’ve named both the ID and the meta:resourceKey to “Header1”. This is the way I want to do it, to keep the ID and resourceKey the same, but it’s up to you. The important thing is that the value for Name in the resource file corresponds to the value of meta:resourceKey. In the resource file you also typed .Text after Header1. This is the way to tell Asp.Net which property that should display the text. You can do it the same for buttons or other controls in the same way.

After you’re down, save the file. Now we will create a second language. Create a copy of the newly created resource file in the same directory, and rename it to Default.Aspx.en.resx. This is now the resource file for the English language. Double click the file to open it in the editor and change “Välkommen” to “Welcome”. Save the file.

Now, to let asp.net automatically  determine the language of the calling browser, add the following to your web.config file.

<system.web>
    <globalization culture="auto"  uiCulture="auto"/>

This will tell the asp.net runtime to set the culture for you, and if no resource file is found for the current culture, it will fallback to the words in the file Default.aspx.resx, which is Swedish. So If someone from France browses to this page, they will see the page in Swedish.
Normally, a French person wont understand Swedish, so I decided to add two language buttons in the upper right corner, one for Swedish and one for English. Now, it was here I thought it was just a matter of setting the currentUICulture on the current thread, but it’s more complicated than that. In the click event for each button, I have the following code in the master page.

protected void imgBtSwedish_Click(
object sender, ImageClickEventArgs e)
        {
            this.Response.Redirect("Default.aspx?lang=se");
        }

        protected void imgBtEnglish_Click(
object sender, ImageClickEventArgs e)
        {
            this.Response.Redirect("Default.aspx?lang=en");
        }

The above code actually just redirect the user the default page, with a query string specifying the chosen language.

I know that this is not the correct way of doing this, but it is good enough for just one page. When the web page gets more pages, this will not do it, then I will use the Profile class to set the languages, but more on this in a future post.

This is all the code that are needed in the master page, but in the default.aspx we have to put some code also, to actually set the language.

protected override void InitializeCulture()
{
            if (this.Request["lang"] != null)
            {
                //Swedish is the fallback language
                CultureInfo newCultureInfo = 
new CultureInfo("sv-SE"); switch (this.Request["lang"].ToLower()) { case "en": { newCultureInfo =
new CultureInfo("en-GB"); break; } } Thread.CurrentThread.CurrentCulture =
newCultureInfo; Thread.CurrentThread.CurrentUICulture =
newCultureInfo; } else base.InitializeCulture(); }

The above code overrides the InitializeCulture and checks if there are any language specified, and if so, sets is. Remember to call base.InitializeCulture() if you don't set the language your self, and NOT to call base.InitializeCulture if you do. The base class doesn’t do nothing extra than setting the culture as in this code.

There is much more to Localization than I have written about here, this post jus describes a very simple way to localize a single page with in a master page, in my case enough to display a localized “under construction” page. In the future I will user the Profile class and store language settings for a user in a database. The resource files are XML files, I am also on the search for some great editors. Because the way it is now in Visual Studio, the workflow does not encourage agile development, since I don’t want to open each resource file one at a time, remember the meta:ResourceKey and type the localized word. I want an editor where I can edit all languages at the same time! For now I make all in the default language, and the make copies of the resource file and edit them in the XML-editor, since the built in editor does not handle line breaks very well. To make copies of the resource files works well if you develop on page from top to bottom, and get done with it, but I don’t want to work that way.

Labels: , , ,

kick it on DotNetKicks.com

1 Comments:

Blogger ranganathan.gt@gmail.com said...

Hi all,
Plz say me how to perform localization to multiple pages without using masterpage

19 June 2009 14:42  

Post a Comment

Links to this post:

Create a Link

<< Home