Roman Ratiner 's Blog

Blog on ASP.NET and C#

Tip/Trick: Localization and Master Pages

Today, I found a great solution to create Multilingual Websites (Localization) with Master Pages.

The problem:

You want to create a Master Page for your website with a DropDownList for language changing,but, you can't override InitializeCulture().

The solution:

We can use a Master Page as our template, Default.aspx as a page which will set the Culture and UICulture of the page and User Controls for content.

First, we have to create our Master Page file with at least one ContentPlaceHolder.Then, we will create a Default.aspx page with a PlaceHolder:

Here is the code of Default.aspx page:

<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MySite.Default" Title="Untitled Page" %>

 

<asp:Content ID="pContent" ContentPlaceHolderID="dContent" runat="server">

    <asp:PlaceHolder ID="phContent" runat="server"></asp:PlaceHolder>

</asp:Content>

Now we will code the Page_Load event of Default.aspx:

protected void Page_Load(object sender, EventArgs e)

{

phContent.Controls.AddAt(0, LoadControl("~/Pages/" + Request.QueryString["File"] + ".ascx"));

}

phContent is the PlaceHolderID.We want to load one control, then we load it to position 0.As you can see I used a QueryString("File") as a variable for our User Controls.Finally we have to override InitializeCulture():

protected override void InitializeCulture()

{

if (!String.IsNullOrEmpty(Request.QueryString["DisplayLang"]))

{

if (Request.QueryString["DisplayLang"] == "Auto")

Session["DisplayLang"] = null;

else

Session["DisplayLang"] = Request.QueryString["DisplayLang"];

}

 

if (Session["DisplayLang"] == null)

{

Thread.CurrentThread.CurrentUICulture = new CultureInfo(Request.UserLanguages[0]);

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);

}

 

if (Session["DisplayLang"] != null)

{

string lang = Session["DisplayLang"].ToString();

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang.Remove(2, 3));

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang);

}

base.InitializeCulture();

}

 

So far so good, now we can just use or create an UrlRewriter and use friendly url instead of QueryString.

Comments

jbmixed said:

Its a solution but I think it is not practical

# December 18, 2006 6:15 AM

Aakash said:

article could be more descriptive.

# July 31, 2007 1:02 PM

Dimiter said:

How can I use InitializeCulture() this event fired first before load and buttonclick for language change

# September 14, 2007 6:58 AM

Good Developer said:

I think this is not practical solution.

you can create a base class for pages that override the initlizeCulutre. or you can create two masterpage and switch between masterpages at runtime depending on the culture.

and finally you do not need to write the initlizeculutre in the masterpage becuase it will override it from the contentplace holder!

# September 11, 2009 12:06 AM

Paris said:

Instead of implementing InitializeCulture in every page, and instead of implementing a BasePage class and changing all my pages to inherit from it, I have used another alternative trick for localization.  I store the culture in a Session and then use the PreRequestHandlerExecute handler of Global to set the culture.  My function looks like this:

   protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)

   {

       if ((System.Web.HttpContext.Current != null) && (System.Web.HttpContext.Current.Session != null))

       {

           try

           {

               CultureInfo ci;

               if (Session["culture"] == null)

                   ci = new CultureInfo("en-US");

               else

                   ci = (CultureInfo)Session["culture"];

               // the UI culture suffices for controlling the text on labels

               Thread.CurrentThread.CurrentUICulture = ci;

               // The Culture also affects presets like the Calendar control's month names,

               // but it additionally affects the DateTime.ToShortDateString() returned value

               // as well as all other localizable ToString() calls.

               Thread.CurrentThread.CurrentCulture = ci;

           }

           catch

           {

           }

       }

By the way, you may notice that I check if the session exists.  In general, when this function is triggered, the session will already exist, but the first time the application starts for a user, it might not yet be there.  If the session isn't yet initialized, we don't need to worry about changing the language anyway, so it's fine to exit out of the function until it's called again...it will be called again before a page is actually served to the end-user ;)

# October 1, 2010 2:37 PM