Working with Resources Files, Culture & Regions in .NetResources Files are a way to store data that the application will use such as strings and images which can be translated via localisation.
This article is part of a series of articles. Please use the links below to navigate between the articles.
- Learn to Program in C# - Full Introduction to Programming Course
- Introdution to Programming - C# Programming Fundamentals
- Guide to C# Data Types, Variables and Object Casting
- C# Operators: Arithmetic, Comparison, Logical and more
- Application Flow Control and Control Structures in C#
- Introduction to Object Oriented Programming for Beginners
- Introduction to C# Object-Oriented Programming Part 2
- C# Collection Types (Array,List,Dictionary,HashTable and More)
- Error and Exception Handling in C#
- Events, Delegates and Extension Methods
- Complete Guide to File Handling in C# - Reading and Writing Files
- Introduction to XML and XmlDocument with C#
- What is LINQ? The .NET Language Integrated Query
- Introduction to Asynchronous Programming in C#
- Working with Databases using Entity Framework
- All About Reflection in C# To Read Metadata and Find Assemblies
- Debugging and Testing in C#
- Introduction to ASP.Net MVC Web Applications and C#
- Windows Application Development Using .Net and Windows Forms
- Assemblies and the Global Assembly Cache in C#
- Working with Resources Files, Culture & Regions in .Net
- The Ultimate Guide to Regular Expressions: Everything You Need to Know

Localisation, a crucial aspect of software development, involves writing code that can adapt to the user's locale. This adaptation includes changes in language, date and number formatting, and currency, making the software more user-friendly and accessible across different regions.
Let's apply the concept of localisation to a familiar example, the Hello World application. By localising this simple program, we can demonstrate the techniques and features used in creating global applications. We'll also explore how resource files can be used for localisation and branding, enabling the creation of generic applications with customer-specific branding.
First, look at a simple Hello World application that 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, whether it is Japanese, Chinese, Arabic, or Italian. 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
Adding a resource file to your project is a straightforward process. Simply navigate to the 'Add New Item' menu and select 'Resource File '. To keep your resources organised, it's advisable to create a separate folder within your solution. This resource file will serve as our default language, so let's name it 'resources.resx'.
By default, Visual Studio will show the resource editor; if it hasn't, you can open the file from the solution explorer.
We will need to add a few string resources to the file, one for each string that has been hard-coded in the application.
Key name | Value |
---|---|
HelloWorld | Hello World! |
TheTime | The Time is: {0} |
EnterName | Hello World! |
HelloMessage | Hello {0}. Welcome to our test program. |
Now, our program needs a few changes 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, and you can change the name to match the file you created).
using System;
namespace ConsoleApplication1
{
class Hello
{
public static void Main()
{
Console.WriteLine(resources.HelloWorld);
Console.WriteLine(string.Format(resources.TheTime, DateTime.Now.ToString()));
Console.WriteLine(resources.EnterName);
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
Creating resources for different languages is a flexible process. Simply copy and rename the default language file, including the culture identification. For instance, for France, our 'resources.resx' will be renamed 'resources.fr-FR.resx '. This flexibility allows you to cater to a global audience with ease.
Visual Studio does not compile all the resources into a single output assembly. Instead, it compiles 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 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 to display in the way the user expects.
For example, in England, one million is written as 1,000,000.00, but in France, it is written as 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 and add a currency symbol correctly.
Localisation in ASP.Net
Resources in ASP.Net Applications are created in much the same way as Forms or Console applications. 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 into which we can enter our data. GlobalLanguages can be any name you wish; substitute 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 to the comments column.
Save and close this file, then duplicate it from Solution Explorer, giving it the name of GlobalLanguages.it.resx (it is 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.
ASP.Net resources are strongly typed, as with the applications above, so you can access them with IntelliSense using the methods shown below. After you change the resource files, you must build the project for IntelliSense to pick up extra or modified values.
Displaying Resource Messages with ASP.Net
Now, we only need to output these messages on the screen. There are a few methods for this, so pick the one that best fits 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 on the screen.
Changing Resource Languages
You can change the resource file language displayed by changing the current resource provider culture. The constructor of the CultureInfo class takes the five-character language code from the Messages.xx.resx filename. The code to change to Italian is shown below.
Resources.GlobalLanguages.Culture = new CultureInfo("it");
For this tutorial, I have hard-coded the language. Still, it can be loaded from a configuration file, query string, session variable, 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. The sample download below shows an example of this in action.
The example uses buttons to change the language to English, French, and Italian. 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 resource type from the drop-down list. When you access the key, the strongly typed resources will return an object of the correct class. When you access a string, it will return a string object; 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 to 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.