Practical ASP.NET

Supporting Multiple Languages and Cultures (Part 2)

Peter Vogel dives deeper into the challenge of presenting ASP.NET Web pages in multiple languages and cultures.

To fully support multiple languages and cultures in an ASP.NET site, you'll need use global resources and write some code to access the special features that ASP.NET provides for internationalization.

In last week's column (Supporting Multiple Languages and Cultures), I discussed ASP.NET's base support for internationalization and localization. This week I'm going to discuss some more interesting problems.

One issue that I raised last week was handling those scenarios where the user wanted pages displayed using a different language or culture than is specified in the browser. To support this you need to set up a table to hold the user's preferences (or just use the ASP.NET Profile object) to hold the language or culture that the user wants.

Once you've set up a place to store the user's preference you just need to set the Page's UICulture property to the user's preferred language/culture setting. Assuming that you have a resource file created for that language and/or culture, the page will automatically display the right values. The appropriate way to do this is to override the Page’s InitializeCulture method. This example sets the page to use Spanish language for the Mexican culture:

Protected Overrides Sub InitializeCulture()
        Me.UICulture = "es-MX"
        MyBase.InitializeCulture()
End Sub

Setting the UICulture property in the InitializeCulture method doesn't require that you set the Page's UICulture property to Auto.

Shared Resources
However, this change still only supports translating the content of a single page. Many applications will have message or other text that needs to be shared across multiple pages. You can add these resources to a global resource file that can be accessed from multiple pages.

To add a global resource file, do the following:

  • Select the Web site in Solution Explorer
  • Right-mouse click and select Add ASP.NET Folder | App_GlobalResources
  • Right-mouse click on the new folder and Select Add New Item | Resource File

When the file is first created it will be named filename.resx. As described in last week's column, you'll need to rename the file to indicate the language/culture it contains (e.g. rename the file to filename.es-MX.resx if the file holds "Spanish for Mexico" resources).

Once you've created the file you can add name/value pairs to it where the value is the text that you want to use. For instance, I might create a name/value pair in my en-US ("English for the USA") resource file with a name (or "ResourceId) of "Warning" and a value of "Don't touch"; In my es-MX resource file, I would have the same name but the value would "No toque".

To get your controls to use a value in a global resource file, you can bind the value to a property in the page by specifying the file to use and the ResourceId to select from the file. This example binds the Text property of a Label to a file called WarningMessages and pulls out the value associated with the ResourceId "TouchWarning":

‹asp:Label ID="lblWarning" runat="server"
Text="‹%$ Resources:WarningMessages,TouchWarning %›"›‹/asp:Label›

Once again, ASP.NET will use the correct resource file based on the browser's settings (provided you've set the Document's UICulture property to Auto) or any overrides you've put in the InitializeCulture method.

While binding a property in the aspx file will handle text common to many pages that never change, it won't handle a label that displays error messages that change dynamically. To handle that you'll need to stop returning text error messages to your user interface. Instead, you should return names for items in either your local or global resource files. For global resource files, you can then use the .NET GetGlobalResourceObject to retrieve a value by passing the name of the ResourceFile and the value's ResourceId.

This example sets the Text property of a label from a resource file called ErrorMessages, passing the value in the variable ErrorId as the ResourceId to retrieve:

Me.lblError.Text = GetGlobalResourceObject("ErrorMessages", ErrorId).ToString

Again, ASP.NET will load the right resource file based on the browser's settings (with UICulture set to Auto) or values set in the InitializeCulture method.

Obviously, I haven't covered everything here (I've ignored displaying dates, numbers and currencies, for instance). For those you can use the standard .NET classes (e.g. passing the CurrentUICulture property on the CurrentThread Object to the ToString method of a Date object).

Notice that at no point are you obliged to compile your resource files into DLLs, though you certainly can. Here is a good discussion of ASP.NET support for internationalization and localization, which includes instructions on how to create resource DLLs. As the author points out, that feature is really only there for developers distributing custom controls and WebParts.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events