Learning never exhausts the mind


Localisation is the process of writing software that is able to sense the user's locale and change its behaviour based on that information. This includes language, date and number formatting and currency.
Introduction to Programming with C# Series
  1. Introduction to Programming with C# 7
  2. C# Programming Fundamentals
  3. Introduction to Object-Oriented Programming
  4. C# Object-Oriented Programming Part 2
  5. Flow Control and Control Structures in C#
  6. C# Data Types, Variables and Casting
  7. C# Collection Types (Array, List, Dictionary, Hash Table)
  8. C# Operators: Arithmetic, Comparison, Logical and more
  9. Using Data in C# 7 with ADO.Net & Entity Framework
  10. LINQ: .NET Language Integrated Query
  11. Error and Exception Handling in C#
  12. Advanced C# Programming Topics
  13. Reflection in C#
  14. What Are ASP.Net Webforms
  15. Introduction to ASP.Net MVC
  16. Windows Application Development
  17. Assemblies and the Global Assembly Cache in C#
  18. Working with Resources Files, Culture & Regions
  19. Regular Expressions in C#
  20. Introduction to XML with C#
  21. Complete Guide to File Handling in C#

We revisit the Hello World application and localise it to demonstrate the techniques and features used in created global applications. We will then look at resource files and see how they can be used for localisation and storing branding, allowing you to create generic applications with customer specific branding.

First, let's see a simple Hello World application which shows the current date and time.

using System;
class Hello
  public static void Main()
    Console.WriteLine("Hello World!");
    Console.WriteLine("The Time is: " + DateTime.Now.ToString());
    Console.WriteLine("Please enter your name: ");
    string name = Console.ReadLine();
    Console.WriteLine("Hello " + name + ". Welcome to our test program.");

When it is run, the application will look the same regardless of the user's locale, be it Japanese, Chinese, Arabic or Italian. In order to localise the application, we need to remove all references to hard-coded values, but first, we need to create our resource file.

Adding Resource Files to Applications

This is done by adding a resource file to the project from the "Add New Item" menu. It is advisable to create these resources within a separate folder in your solution to keep them together. This resource file will be our default language so name it "resources.resx".

By default, Visual Studio will show the resource editor, if it hasn't shown you can open the file from the solution explorer.

We are going to need to add a few string resources to the file, one for each string that has been hard-coded in the application.

Key nameValue
HelloWorldHello World!
TheTimeThe Time is: {0}
EnterNameHello World!
HelloMessageHello {0}. Welcome to our test program.

Now our program needs a few changes in order to display these new values. Since the resources file is a strongly typed data object we can use resources as an object and access its properties (resources are the name of the resource file. You can change the name to match the file you created).

using System;
namespace ConsoleApplication1
  class Hello 
    public static void Main()
      Console.WriteLine(string.Format(resources.TheTime, DateTime.Now.ToString()));
      string name = Console.ReadLine();
      Console.WriteLine(string.Format(resources.HelloMessage, name));

Now we have an application with no hard-coded strings. You will notice that I have used a string.Format to output data. This allows different languages to change the position of a name or any data object within the string.

Adding Languages to Resources

To create different language resources simply copy the default language file and rename it including the culture identification, e.g. for France our resources.resx will be renamed resources.fr-FR.resx.

Visual Studio does not compile all the resources into a single output assembly. Instead, it compiles each of these localised resource files into a separate assembly called satellite assemblies.

Your project structure will now look like this:

- ConsoleApplication1.exe
- fr-FR
- - ConsoleApplication1.resources.dll
- it-IT
- - ConsoleApplication1.resources.dll
- de-DE
- - ConsoleApplication1.resources.dll

You will notice that the default resources are not shown, this is because they have been compiled into the application executable.

You can also generate satellite assemblies manually using the Assembly Linker tool, details of which can be found in our tutorial Creating and Implementing Satellite Assemblies.

This technique can also be used for using application settings.

Localized Number Formatting

In addition to strings, other data such as currency, dates and numbers must also be localised so that they display in the way the user will expect.

For example, in England, one million is written 1,000,000.00 but in France, it is written 1 000 000,00 and in Germany 1.000.000,00.

Numbers can be written using the correct formatting using the ToString method of the object.

int i = 1000000;
Console.WriteLine(" " + i.ToString("N"));

Where N is the format character for an int. If you are outputting currency you can use C instead, which will format the number as well as add a currency symbol in the correct place.

Localisation in ASP.Net

Resources in ASP.Net Applications are created in much the same way as Forms or Console application. Simply create a new ASP.Net folder by right-clicking on the project in Solution Explorer, followed by Add ASP.Net Folder, then App_GlobalResources. Next, right click on this new folder and Add New Item. Select Resource and call it 'GlobalLanguages.resx'.

This will create the default language file and Visual Studio will then display the resource designer window where we can enter our data into. GlobalLanguages can be any name you wish, just substitute in your name for GlobalLanguages in the code below.

On the left column (name) you enter an identifier name for the string, for example, "WelcomeMessage" and in the right-hand column (value) enter the actual message, for example, "Hello and Welcome to our Website". You can optionally add information into the comments column.

Save and close this file, then from Solution Explorer duplicate this file, giving it a name of GlobalLanguages.it.resx (it being the two-letter country code for Italy/Italian). Replace "Hello and Welcome to our Website" with the Italian "Ciao e benvenuto al nostro Website". Save and close this file.

As with the applications above, ASP.Net resources are strongly typed, so you can access them with IntelliSense using the methods shown below. After you make changes to the resource files you will need to build the project for IntelliSense to pick up on the extra or modified values.

Displaying Resource Messages with ASP.Net

Now, all we need to do is output these messages on the screen. There are a few methods for this, so pick the best one for your needs.

Setting the value of a label in the C# code behind

Label1.Text = Resources.GlobalLanguages.WelcomeMessage;

Raw HTML in the ASPX

<a href="#"><%=Resources.GlobalLanguages.WelcomeMessage %></a>

Reading the Value into a String object

string WelcomeMessage = Resources.GlobalLanguages.WelcomeMessage;

When you run the application you will see the English message written out on the screen.

Changing Resource Languages

You can change the resource file language that is displayed by changing the current resource provider culture. The constructor of the CultureInfo class takes the five character language code to use from the Messages.xx.resx filename. Shown below is the code to change to Italian.

Resources.GlobalLanguages.Culture = new CultureInfo("it");

For the purposes of this tutorial I have hard-coded the language, but it can be loaded from a configuration file, query string, session variable or profile information or any other method you desire. If you specify a language to the CultureInfo that does not have a Messages.xx.resx file then the default Messages.resx will be used.

You can also use string placeholders in the resource file, so you could have a string "Welcome back {0}, you have {1} new messages" and use a string.format to enter usernames and numbers. You can see an example of this in action in the sample download below.

The example uses three languages - English, French and Italian with buttons to change the language. I am also outputting the date so I have changed the System.Threading.Thread.CurrentThread.CurrentCulture to match the language selected so that when the day is outputted the system automatically outputs the correct day for the language.

Using Resource Files in C# Applications

As well as being used for application localisation, resource files can also be used to hold files associated with the application, such as images, sounds and other data objects. For example, you can create a generalised application and use resource files and satellite assemblies to create custom branded or specific applications without recompiling the application.

Resources can hold many different types, including Bitmap images. In the resource editor, you can change the type of resource from the drop-down list. The strongly typed resources will return an object of the correct class when you access the key. When you access a string it will return a string object and when you access an image it will return a Bitmap object.

Bitmap bmp = applicationStringResources.MyLogo;

Assemblies can be individually compiled into DLL satellite assemblies which can be dropped into the application directory or global assembly cache so they can be used at runtime using the ResourceManager. The process of creating and using satellite assemblies is described in more detail in the Creating and Implementing Satellite Assemblies tutorial.


Enjoyed this post? Why not share it!

If you enjoyed this post, please share it with others. Click one of the social media buttons below to share on Facebook, Twitter, LinkedIn, Pinterest or email to a friend.

0 thoughts on “Working with Resources Files, Culture & Regions
  • Ekrem SABAN
    19th August 2011 at 12:00 am

    Found what was missing: I had to select on the top of the applicationResourceDE in the combo box "Internal" (defaults to "no code generation").

  • Ekrem SABAN
    19th August 2011 at 12:00 am


    I am asking about a bit more complicated case, where the "Hello, World!" program can also greet the World in German.

    I modified your code to
    static void Main(string[] args)
    Console.Write("0: English, 1: German");
    int language = Console.Read();

    switch (language)
    case 1: // de
    default: // en


    I also created a second resource with the name above for German that has the same "Hello" label in it. All done in Microsoft Visual Studio 2010 Express...

    When I now try to run it, there is a compile-time error which reads

    The name "applicationResourcesDE" does not exist in the current context.

    So, I am asking about the more complicated case of creating somehow a "current context" that also "knows" about German greeting...

    Thank you for your reply!

  • 3rd April 2011 at 12:00 am

    I have a list of strings stored in a file called as "Data.txt" that i have added to the Resources.resx.
    Now, i was to compare it with a String stored in the Windows form.
    I know that i can access the file using
    but now how can i compare its contents with the sting stored in Windows Application From.
    Like i have :-
    string s1 = "bus";
    and in the Data.txt , I have i list like this....

    So, how can i compare this list in Data.txt with "s1" and find out if s1 is a part of Data.txt or not....??
    P.S. :- "Please Help"


Leave a Reply

Fields marked with * are mandatory.

We respect your privacy, and will not make your email public. Hashed email address may be checked against Gravatar service to retrieve avatars. This site uses Akismet to reduce spam. Learn how your comment data is processed.