Click here to Skip to main content
Email Password   helpLost your password?

Introduction

While seeking on the internet for a solution to implement localization within an ASP.NET application using a MasterPage, I realized that a lot of people have got the same problem to solve. Unfortunately, I could not find a suitable solution thus, I intended to do my own implementation.

Background

The solution presented within this article uses the standard localization mechanism of the .NET framework.

Using the code

The published solution uses the Session object as storage for the currently selected culture. This will be initialized during the Session_Start method that is part of the global.asax file.

If a culture change is requested by the user, the MasterPage changes the stored culture in the Session object.

In a BasePage that inherits from Page, the method InitializeCulture is overridden and sets the appropriate culture information stored in the Session object to the current thread. Therefore, every Web Form needs to derive from this BasePage.

Let's start with the Global.asax file:

void Session_Start(object sender, EventArgs e) 
{
    //set english as default startup language
    Session["MyCulture"] = "en-GB";
}

Alternatively, the culture can be defined in the Web.config file with the key <globalization culture="en-GB" /> and then be processed and stored in the Session object from the Session_Start method.

The next step is the master page:

<%@ Master Language="C#" AutoEventWireup="true" 
           CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>[Smart-Soft - Masterpage with Localization Support]</title>
</head>

<body>
    <form id="theForm" runat="server">
    <div>
        <asp:contentplaceholder id="ContentPlaceHolder" runat="server">
        </asp:contentplaceholder>
    </div>
    <div style="margin-top:20px;">
        <asp:LinkButton ID="btnSetGerman" runat="server" Text="Deutsch" 
           CommandArgument="de-CH" OnClick="RequestLanguageChange_Click">
        </asp:LinkButton>  
        <asp:LinkButton ID="btnSetEnglish" runat="server" Text="English" 
           CommandArgument="en-GB" OnClick="RequestLanguageChange_Click">
        </asp:LinkButton>
    </div>
    </form>
</body>
</html>

The buttons to change the culture can be either placed in the MasterPage directly, or in any embedded UserControl. In order to determine the requested language, the CommandArgument attribute of the LinkButton is used.

..And the code-behind of the master page:

public partial class MasterPage : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void RequestLanguageChange_Click(object sender, EventArgs e)
    {
        LinkButton senderLink = sender as LinkButton;

        //store requested language as new culture in the session
        Session["MyCulture"] = senderLink.CommandArgument;

        //reload last requested page with new culture
        Server.Transfer(Request.Path);
    }
}

The requested language, passed within the CommandArgument, is processed and stored in the Session object. Afterwards, the initially requested page will be reloaded on the server side.

Last but not least, the BasePage:

/// <summary>
/// Custom base page used for all web forms.
/// </summary>
public class BasePage : Page
{
    private const string m_DefaultCulture = "en-GB";
    
    protected override void InitializeCulture()
    {
        //retrieve culture information from session
        string culture = Convert.ToString(Session["MyCulture"]);

        //check whether a culture is stored in the session
        if (!string.IsNullOrEmpty(culture)) Culture = culture;
        else Culture = m_DefaultCulture;

        //set culture to current thread
        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

        //call base class
        base.InitializeCulture();
    }
}

As mentioned above, the InitializeCulture method is overridden, and gets the stored culture from the Session object and assigns it to the currently running thread.

Remark: In this article, only the culture was mentioned. Of course, there is also the UI culture. But it is not of any further interest in this article since the handling is absolutely identical. For more information, please see the MSDN pages. :)

For a running example, download the Zip file above.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralGreat work!
jonrandahl
3:20 15 Sep '09  
First, thanks for all the hard work on this, it's helped me understand localisation a whole lot more!
second, even though my localised content is changing on the individual pages, I still need to change items in the masterpage which don't seem to switch at all? I've used the "Generate Local Content" tool on the masterpage, set the server controls collected to the right language phrases, but there doesn't seem to be any difference?

Does anyone know why this is or if this is even possible?

Thanks again for your hard work, and sharing with us!
J
GeneralMerci vielmal ;-)
Darkjo
22:24 12 Aug '09  
Thanks to share this great solution Cool

Regards
Questionerror in localization using masterpage
mdazeemuddin
2:53 31 May '09  
Hi,

your code is very nice

i used your code in my application but i got one error i used one master page and 10 to 15 other pages which is using master page i mean in other page i put content place holder i put two link button in my master page name as English and Arabic and i create a Global.asax file and i create basepage also i have done what you explain in your artical but my question or my problem is i have one page orderonline for that page i create resource file in arabic and english when i open any page other then orderonline page i can translate text from arabic to english or vise versa when i try to translate from order online page then the link button not generating the onclick event from the other page its working fine and one more thing in cs files of all pages i used inheritance as system.web.ui.page and in order online page i used inheritance as basepage class as u said

i think i clear my point.

thank in advance for help
AnswerRe: error in localization using masterpage
Michael Ulmann
3:06 31 May '09  
Hi,

I don't fully understand your issue.

You mentioned that all your pages derive from the standard .NET System.Web.UI.Page class except the OrderOnline page wich derives from the BasePage, right? This results in not having the users selected culture applied in any page but the OrderOnline page. But I assume that the idea would be that all pages support localization and hence, they should all derive from the BasePage class.

What do you exactly mean by you can translate? Are we talking about adding/changing resources or runtime behaviour by clicking one of the language selection buttons e.g. page localization?

Would be good if you could give me a bit more information or even a small demo solution where I can have a look at to determine the problem. You can send this to ukmichael@hotmail.com if you like.

Cheers,
Michael
GeneralRe: error in localization using masterpage
mdazeemuddin
5:37 31 May '09  
thanks for your support

you understand what i want to say.ya my all pages derive from the standard .NET System.Web.UI.Page class except OrderOnline Page which is derives from the base page

i will try to tell clearly what i want say is i run my application it open Default.aspx which is my startup page and this page is derive from standard .NET System.web.UI.Page class. If i select language as Arabic its perfectly translating my application into Arabic. If i open OrderOnline page which is derive from BasePage class
and i try to change my application language either English to Arabic or Arabic to English its simply submitting the OrderOnline form instead of doing translation.

why it is happening i don't know but i try lot to remove this bug but couldn't

so please help me where i am doing mistake.

thanks for your support
GeneralRe: error in localization using masterpage
Michael Ulmann
17:05 3 Jun '09  
Hi,

I've sent you your demo solution back. It's working now.

It might be interesting for other ppl too what was the actual issue.

Apparently, the invariant culture resource file was missing and hence, the .NET framework wasn't able to get the translated strings.

Cheers
GeneralTerrible Code!
TV Mogul
6:44 26 Apr '09  
Hi,

Your code sample is terrible!

Just add a new page tp the sample and you will see that the whole project crashes because the second page can't find any named resources!

I am amazed that nobody else saw this HUGE bug... really bad code!

Bill

www.FrreTVDating.com
TV Mogul

GeneralRe: Terrible Code!
Michael Ulmann
15:41 26 Apr '09  
Dear Bill,

I understand that you may be frustrated by the fact that you haven't understood how the .NET framework utilizes resources.
Have you by any chance thought about that you might have done something wrongly since you are obviously the only one experiencing this problem?

Basically, there are two ways you can use resources in a web application.
Firstly, you can have the resources organized on a per page/uc basis. That means that you need to place your resource file in the App_LocalResources folder using the same file name as the page/uc suffixed by ".resx".
Alternatively you may want to manage your resources in a central pool. In this case you would place them all in the App_GlobalResources folder in the web root. That would mean that every time you are referencing a resource in your code that you have to specify in which global resource file the resource is stored. E.g. <%$ Resources: PageTitles, DefaultTitle %>
Best practise would be to store resources on a per page/uc basis where resources are closely related to them. Common resources used in various places should be managed in the global resource pool.

Hence, if you try to use resources without properly specifying a resource repository the compilation fails.

I hope this helped eliminating your frustrations.

Cheers,
Michael

GeneralRe: Terrible Code!
TV Mogul
1:30 27 Apr '09  
Hi,

I appreciate your classy reparte. Indeed you do have style and class and I am impressed your resisting any name calling Michael.

The fact is that I do understand how Culture works in aspn .net but the way you wrote the code, doesn't allow adding a second page --- go ahead, take your code and add a secomd page to the sample.

I have built several large multi-language websites and if you have a lot of pages then you might want to consider local resources and if you only have a few pages with a limited number of total resources then global might work better. But in either case your code sample still won't allow you to add another page--try it...

Bill

www.FrreTVDating.com
TV Mogul

GeneralRe: Terrible Code!
TV Mogul
1:49 27 Apr '09  
Hi,

I should have explained why I thought your code was terrible and I apologize for not explaining this in my first comment.

An article is supposed to illustrate the techniques used and in your response to my comment whiich showed a lot of class on your part, you do explain the point I was trying to make. My point was that if you had included your response to me as part of the article, then a reader would be clear that you need to add separate resource files for EACH page.

In addition, for this to be a good article you should have included 2 pages, discussed why you don't need url re-writing, and added a global resource, and an example using 2 images, one for each language. Then you would have a great article. Also, I was wrong in describing the code as "Terrible" and what I meant was that he article failed to illustrate some very important points on using resources.

I confess that I sometimes emjoy phrasing things my comments in a way to invoke a response, but your response was indeed impressive. Another reader commented earlier on this same issue of adding another page which he finally figured out required a separate resource.

Bill

www.FrreTVDating.com
TV Mogul

GeneralVery nice article
Ezz Khayyat
2:20 24 Dec '08  
Thanks for the great article.

I think it works also without sub classing the Page class.

I've created a sub class from the MasterPage class, and there I put a method ChangeLanguage as follows:


    public enum UILang
{
EN = 0,
AR = 1 }


public class MultiLingualMasterPage : System.Web.UI.MasterPage
{
protected void SetLanguage(UILang aLang)
{
// The new culture
CultureInfo culture = null;

// Create new culture based on selected language
switch (aLang)
{
case UILang.AR:
// Create the CultureInfo object for Arabic-Jordan
culture = new CultureInfo("ar-JO");
break;

case UILang.EN:
// Create the CultureInfo object for English-United States
culture = new CultureInfo("en-US");
break;
}

// Assigns the new culture to the current thread, thus making it dominating
Thread.CurrentThread.CurrentCulture = culture;

// Let the Resource manager make use of appropriate language's XML file
Thread.CurrentThread.CurrentUICulture = culture;

// Reload last requested page with new culture
Server.Transfer(Request.Path);
}
}


So the culture is applied directly from within the master page, and hence, no need to sub class the Page class & override the InitializeCulture() method.

I tested it & it works like a charm Smile

Again, thanks for the great article. It was really useful to me Wink

GeneralRe: Very nice article
Ezz Khayyat
13:14 24 Dec '08  
Oops sorry!

Seems I need to apply the culture on every postback/request!

Your Page sub class is the best dude Smile

Cheeeeeeeeeers
GeneralBest Localization Plug-in for Visual Studio.
Alexander Nesterenko
22:34 17 Dec '08  
Move strings from code to resx and translate their automatically. Try RGreatEx[^] free.

---
Best regards,
Alexander Nesterenko
Safe Develop Team
www.safedevelop.com

Generalgreat article
Simon Griffiths
2:49 3 Dec '08  
many thanks
Generalresource tags in master page
daniel.zolnjan
9:26 23 Oct '08  
How to add resource enabled control to masterpage markup

<asp:literal id="litPageTitle" runat="server" text="<%$ Resources:PageTitle %>" xmlns:asp="#unknown">
if placed in masterpage generates "The resource object with key 'PageTitle' was not found."

??
GeneralThanks but I have a problem...
swissroll55
5:54 21 Oct '08  
This is exactly what I needed for my site and I really appreciate the work that went into it.

All worked fine until I tried to add a second page. Then I get:

Error 1 The resource object with key 'lbl1.Text' was not found

it seems default.aspx works ok but no subsequent pages are able to locate the resources they need. I can't find any good reason for this. Even if I make an exact copy of Default.aspx the resources cannot be found for the new page.

Thx

Swissroll
GeneralRe: Thanks but I have a problem...
swissroll55
5:58 21 Oct '08  
ok. I solved my own problem. Overlooked the fact that you need a separate set of resource files for each page.

Happy now!

Smile
GeneralAwesome
Suresh27129
6:52 28 Aug '08  
Thanks for your wonderful work!!!

Regards
Suresh
GeneralGreat!
Shevchenko7
13:44 25 Aug '08  
Great article, very helpful Smile Thanks!
GeneralReally helpful but...
famous
1:49 29 May '08  
Excellent article but in that way we have to place the
InitializeCulture() 
override function in every aspx page. I found the following code in asp.net forums where instead of placing the localization change in every page we just place it in
Application_PreRequestHandlerExecute 
of global.asax and everything goes fine:

if (Context.Session != null && Context.Session["MyCulture"] != null)
{
String selectedLanguage = Context.Session["MyCulture"].ToString().ToLower();
String currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.ToLower();
if (!currentLanguage.Equals(selectedLanguage))
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLanguage);
}
}

In my case where changing the language from a master page imagebutton it works perfectly.
I just post it in case anyone finds that helpful.

In conclusion your article was really helpful.
Thanks.

Stelios

GeneralExcellent Article
M_Menon
2:17 21 May '08  
I was trying to overload the InitializeCulture() inside my Control form and i was getting an error. Well you found the solution.. INHERITANCE...base class and all OOPS concepts.

Excellent Article. Keep up good work. Hope to see more articles from you.

Cheers

Menon

GeneralInitializing the language automatically
Guillaume Hanique
0:24 8 May '08  
Hi, great article on how to change languages on a site!

It could also be initialized by looking at Request.UserLanguages(0), which is the language the user set in his/her browser. So mine could be set to German, while someone else's might be set to English. That way the site will display in the user's primary language.
GeneralRe: Initializing the language automatically [modified]
Member 2242004
10:17 10 Sep '09  
Hi,

Have you code snippet that will work with this sample.

modified on Thursday, September 10, 2009 3:28 PM

GeneralHot
paulklee
18:11 5 May '08  
Thanks a lot for sharing that!
GeneralPerfect example for localization
fristi
5:13 24 Mar '08  
thnx
Bart


Last Updated 7 May 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010