Click here to Skip to main content
Click here to Skip to main content

Dynamic definition of the list of available languages for an ASP.NET web page

By , 28 Feb 2011
Rate this:
Please Sign up or sign in to vote.

Introduction

In this article, we will learn how to dynamically define a list of available languages for an ASP.NET web page.

Requirement

Microsoft® Visual Web Developer® 2010 Express and higher. Web-site with localization that is based on the use of resource files (.resx) for localization.

Why and when this can be helpful

The main advantage of this functionality is to get rid of a static list of supported languages on the web page. With this functionality, you can have a different number of supported languages for each page. Each page will determine the list of supported languages based on the resource files existing for the page.

How to implement

To use this functionality, you need to do three things:

  1. Inherit each web page class which is intended to use this functionality from a base class - BasePage.
  2. Add to your web site two files: BasePage.cs and Cultures.cs.
  3. Bind a control on the page intended for display and language selection to a page with the list of available languages for the page. The list of available languages would provide a method GetAvailableCultures from a Cultures class.

How it works

As an example, I will suggest a site that is created by Visual Studio as a template for a new web-site with a Master page, Default page, and an About page as well. For decreasing the project size, I will not take into account other files for authentication functionality etc. I will try to show all the functionality on the example with two pages: Default.aspx and About.aspx. For this example, I have added some resource files (with absolutely different cultures for both pages) and will show how to dynamically define a list of available cultures on each page.

After defining the project structure, we will continue with the implementation details.

First of all, let’s see the root file for this feature, Cultures.cs. Here is the code:

public class Cultures
{
    public static readonly string DEFAULT_CULTURE_NAME = "en";

    public IList<string> GetAvailableCultures(string directoryPath, string fileName)
    {
        // Used in WriteLine to trim output lines.
        int trimLength = directoryPath.Length;

        // Take a snapshot of the file system.
        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(directoryPath);

        // This method assumes that the application has discovery permissions
        // for all folders under the specified path.
        // Provide a search for the appropriate files
        IEnumerable<System.IO.FileInfo> fileList = 
          dir.GetFiles(string.Format("{0}.*.resx",fileName), 
          System.IO.SearchOption.AllDirectories);

        // Select out the name of culture from the list of resource files
        IList<string> Cultures = fileList
            .Select(x => x.Name.Split('.')[x.Name.Split('.').Length - 2].ToString())
            .Distinct()
            .Where(y => y.Length < 8 && y != "aspx").ToList<string>();

        Cultures.Add(DEFAULT_CULTURE_NAME);

        return Cultures;
    }
}

The main function in this class is GetAvailableCultures and it gets us the list of available cultures based on the resource files available for the current page.

When we get a list of all the available cultures, we can think about how to show it. For this issue, I will use a dropdown control which will be filled with the cultures on the Master page Page_Load handler.

There is also another interesting question - how to change the culture of the page if the user changes it using the dropdown on the master page? There exists a good explanation for this issue here on CodeProject: http://www.codeproject.com/KB/aspnet/localizationByVivekTakur.aspx.

Following this example, we can implement such a code for the Site.Master.cs code-behind:

public partial class SiteMaster : System.Web.UI.MasterPage
{
    protected string CalledPageName { get { 
      return HttpContext.Current.Request.
               AppRelativeCurrentExecutionFilePath.Substring(2); } }    
   
    protected void Page_Load(object sender, EventArgs e)
    {

        // Select choosen language after the page was reloaded
        if (this.IsPostBack == false)
        {
            //if (Cache[CalledPageName] != null) Cache.Remove(CalledPageName);
            IList<string> CultureList = null;
            if (Cache[CalledPageName] != null)
                CultureList = (IList<string>)Cache[CalledPageName];
            else
            {
                // Get a list of availabele cultures
                // based on an appropriate resource files 
                Cultures c = new Cultures();
                CultureList = c.GetAvailableCultures(
                     System.IO.Path.GetDirectoryName(
                         Request.PhysicalPath)
                         , CalledPageName
                         );
                Cache[CalledPageName] = CultureList;
            }

                // Add all available languages to Dropdown list "Choose Language"
                foreach (string culture in CultureList)
                    ddlChooseCulture.Items.Add(new ListItem(
                      CultureInfo.GetCultureInfo(
                      culture).NativeName.ToLowerInvariant(), culture));

                if (CultureList.Count == 0)
                    ddlChooseCulture.Items.Add(new ListItem(
                      CultureInfo.GetCultureInfo(
                      Cultures.DEFAULT_CULTURE_NAME).NativeName.ToLowerInvariant(), 
                      Cultures.DEFAULT_CULTURE_NAME));
                if (Session["CurrentCulture"] != null)
                    ddlChooseCulture.SelectedValue = (string)Session["CurrentCulture"];
                else
                {
                    if (ddlChooseCulture.Items.FindByValue( 
                           System.Threading.Thread.CurrentThread.
                           CurrentUICulture.TwoLetterISOLanguageName) != null)
                        ddlChooseCulture.SelectedValue = 
                          System.Threading.Thread.CurrentThread.
                          CurrentUICulture.TwoLetterISOLanguageName;
                    else
                        ddlChooseCulture.SelectedValue = Cultures.DEFAULT_CULTURE_NAME;
                }
            }
        }

        protected void ddlChooseCulture_SelectedIndexChanged(object sender, EventArgs e)
        {
            Session["CurrentCulture"] = ddlChooseCulture.SelectedValue.ToString();
            Response.Redirect(Request.Url.AbsoluteUri);
        }
    }

This requires us to override the InitializeCulture() method on the page code-behind class. But it is not a good practice to implement the same piece of code on each page. So, the solution is to create a BasePage class which will provide the core functionality for all the pages. Now, each page that requires localization should inherit the BasePage class.

The base class implementation includes this code:

public class BasePage : System.Web.UI.Page
{
    /// <summary>
    /// Initialize choosen culture
    /// </summary>
    protected override void InitializeCulture()
    {       
        string language = string.Empty;
        if (Session["CurrentCulture"] != null)
            language = (string)Session["CurrentCulture"];

        if (!string.IsNullOrEmpty(language))
        {            
            Thread.CurrentThread.CurrentCulture =  
                   CultureInfo.CreateSpecificCulture(language);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(language);
        }
        base.InitializeCulture();
    }
}

Summary

This article covers the basic fundamentals of using a dynamic definition of culture that is based on existing resource files for a specified page. Hope you have learned something new from this article. Please share your valuable feedback and suggestions to improve this.

License

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

About the Author

Alexey Prosyankin
Software Developer Ciklum
Ukraine Ukraine
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 28 Feb 2011
Article Copyright 2011 by Alexey Prosyankin
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid