Click here to Skip to main content
15,886,199 members
Articles / Web Development / ASP.NET

Master Page Globalization

Rate me:
Please Sign up or sign in to vote.
4.47/5 (9 votes)
13 Mar 2009CPOL3 min read 75.7K   32   13
Completely page independent solution for Master Page globalization.

Introduction

This article explains a page independent way of performing Master Page globalization. Implementation details and complete code snippets are included.

Background

The difficult thing about doing Master Page globalization is that the MasterPage class does not have the InitializeCulture method for us to override. This is significant because the InitializeCulture method is called very early in the page life cycle, and thus is able to affect the initialization of the controls. None of the methods of the MasterPage class can do this. (The best we could do with MasterPage is OnInit, which is not early enough.)

To get around this problem, we have three choices:

  1. Override the InitializeCulture method in the pages that use the master page.
  2. Set the culture in one of the MasterPage's event handlers and reload the master page to recreate the controls.
  3. Set the culture in Global.asax. Global.asax is the first thing called upon page request, and thus provides us with a way to affect control creation.

Because the culture of the current thread resets to default on page redirect and other events, the culture setting process has to take place per request. For this reason, the second solution mentioned above is not acceptable for performance and user experience reasons.

Many articles and forum posts talk about how to implement the first solution. Instead of having InitializeCulture in each page, a more elegant way is to have a base page that handles the culture setting and is inherited by all the pages in the website/web application.

In this article, I would like to talk about the third solution, which allows developers to simply drop a master page to the website/application and make the culture switch work. Implementation details are explained in the following sections.

Setting the Culture in Global.asax

The first task we have here is setting the culture in Global.asax. Cookies are used here because session objects are not accessible in the context when BeginRequest executes.

Global.asax:

C#
protected void Application_BeginRequest(object sender, EventArgs e)
{
     HttpCookie cookie = Request.Cookies["CultureInfo"];

     if (cookie != null && cookie.Value != null)
     {
         Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
         Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);
     }
    else
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-CA");
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-CA");
    } 
}

The code reads the stored culture information from the cookie and uses it, if it's not null, to set the current thread culture.

Use a Drop Down List to Change the Culture

The next task is to add the drop down list to the master page.

.Master:

ASP.NET
<asp:DropDownList ID="ddlLanguage" runat="server" 
       OnSelectedIndexChanged="ddlLanguage_SelectedIndexChanged"
       AutoPostBack="true">
    <asp:ListItem Text="<%$ Resources:Resource, users_English %>" Value="en-CA" />
    <asp:ListItem Text="<%$ Resources:Resource, users_French %>" Value="fr-CA" />
</asp:DropDownList>

Then, we implement the drop down list event handler that stores the selected culture value in the cookie.

.Master.cs:

C#
protected void ddlLanguage_SelectedIndexChanged(object sender, EventArgs e)
{
    //Sets the cookie that is to be used by Global.asax
    HttpCookie cookie = new HttpCookie("CultureInfo");
    cookie.Value = ddlLanguage.SelectedValue;
    Response.Cookies.Add(cookie);

    //Set the culture and reload the page for immediate effect. 
    //Future effects are handled by Global.asax
    Thread.CurrentThread.CurrentCulture = 
                  new CultureInfo(ddlLanguage.SelectedValue);
    Thread.CurrentThread.CurrentUICulture = 
                  new CultureInfo(ddlLanguage.SelectedValue);
    Server.Transfer(Request.Path);
}

As stated in the comments above, setting the culture and performing a reload forces the thread culture to change immediately.

Display the Current Culture in the Drop Down List

Finally, we would like the drop down list to have the current culture as the selected value.

.Master.cs:

C#
protected void Page_Load(object sender, EventArgs e)
{
    //only does it on non-postback because otherwise the selected 
    //value will not reach event handler correctly 
    if (!Page.IsPostBack)
    {
        ddlLanguage.SelectedValue = Thread.CurrentThread.CurrentCulture.Name;
    }
}

Note that it only happens for non-postback events. If we do it for postback events as well, the user selection will be overridden before it reaches the event handler. Another way of getting around this problem is by polling the selected value of the drop down list in Global.asax.

Complete Code Snippets

Global.asax:

C#
protected void Application_BeginRequest(object sender, EventArgs e)
{
     HttpCookie cookie = Request.Cookies["CultureInfo"];

     if (cookie != null && cookie.Value != null)
     {
         Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
         Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);
     }
    else
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-CA");
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-CA");
    }

}

.Master.cs:

C#
protected void Page_Load(object sender, EventArgs e)
{ 
    //only does it on non-postback because otherwise 
    //the selected value will not reach event handler correctly
    if (!Page.IsPostBack)
	{
        ddlLanguage.SelectedValue = Thread.CurrentThread.CurrentCulture.Name;
    }
}

protected void ddlLanguage_SelectedIndexChanged(object sender, EventArgs e)
{
    //Sets the cookie that is to be used by Global.asax
    HttpCookie cookie = new HttpCookie("CultureInfo");
    cookie.Value = ddlLanguage.SelectedValue;
    Response.Cookies.Add(cookie);

    //Set the culture and reload for immediate effect. 
    //Future effects are handled by Global.asax
    Thread.CurrentThread.CurrentCulture = new CultureInfo(ddlLanguage.SelectedValue);
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(ddlLanguage.SelectedValue);
    Server.Transfer(Request.Path);
}

.Master:

ASP.NET
<asp:DropDownList ID="ddlLanguage" runat="server" 
           OnSelectedIndexChanged="ddlLanguage_SelectedIndexChanged"
           AutoPostBack="true">
    <asp:ListItem Text="<%$ Resources:Resource, users_English %>" Value="en-CA" />
    <asp:ListItem Text="<%$ Resources:Resource, users_French %>" Value="fr-CA" /> 
</asp:DropDownList>

History

  • March 12, 2009 - Created the article with problem description and code snippets in it.
  • March 13, 2009 - Added topic discussion and code description.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHelp implementing Pin
Antonio JVS12-Sep-15 7:27
Antonio JVS12-Sep-15 7:27 
QuestionUpdate and Question Pin
condee7824-Oct-12 15:44
condee7824-Oct-12 15:44 
AnswerRe: Update and Question Pin
Tom Lint28-May-13 10:12
Tom Lint28-May-13 10:12 
QuestionProblem Object Pin
bombai18-Apr-12 22:29
bombai18-Apr-12 22:29 
AnswerRe: Problem Object Pin
Member 1355551317-Dec-17 3:28
Member 1355551317-Dec-17 3:28 
GeneralMy vote of 5 Pin
Fagner Ribeiro12-Jan-12 1:44
Fagner Ribeiro12-Jan-12 1:44 
QuestionGlobal.asax Compiled Pin
Fagner Ribeiro12-Jan-12 1:43
Fagner Ribeiro12-Jan-12 1:43 
GeneralMy vote of 4 Pin
GrettirStrong8-Nov-11 10:27
GrettirStrong8-Nov-11 10:27 
QuestionA little problem implementing this code. Pin
GaryZero5-Oct-11 5:35
GaryZero5-Oct-11 5:35 
AnswerRe: A little problem implementing this code. Pin
Hamid Noorbakhsh25-Oct-11 8:46
professionalHamid Noorbakhsh25-Oct-11 8:46 
QuestionThanks for your article Pin
GrayLensman26-Jan-11 9:31
GrayLensman26-Jan-11 9:31 
GeneralGlobal.aspx Inherits from Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication Pin
Member 350345315-Dec-09 2:46
Member 350345315-Dec-09 2:46 
GeneralYou can also use inheritance Pin
taloweb14-Mar-09 5:58
taloweb14-Mar-09 5:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.