Internationalization (i18n) in C# (.NET): A Complete Guide
Internationalization (often abbreviated as i18n — from the English word "internationalization", where there are 18 characters between the first letter 'i' and the last letter 'n') is the process of designing software so that it can be easily adapted to various languages and regional standards without making changes to the source code. In the C# (.NET) ecosystem, internationalization is a built-in and powerful feature that allows developers to create truly multilingual applications.
In this article, we will take a detailed look at how to implement i18n in .NET (including .NET Core, .NET 5/6/7/8, and .NET Framework). You will learn about key concepts — cultures, resource files (RESX), localization of strings, images, and data formatting.
Key Concepts
Before moving to code, it is important to understand two key terms:
- Globalization: The process of designing an application that supports localized interfaces and regional data for users from different cultures. In .NET, this is achieved through the
CultureInfoandRegionInfoclasses. - Localization: The process of adapting an already globalized application for a specific language/region (e.g., translating texts, configuring date and currency formats).
.NET uses cultures, which are specified in the language-region format (e.g., ru-RU — Russian (Russia), en-US — English (United States), de-DE — German (Germany)).
Step 1: Creating Resource Files (.resx)
The primary way to store localized strings in .NET is through resource files (.resx). They are XML files that are compiled into the assembly.
Let's look at an example. Let's create files for Russian and English languages:
- Resources.resx — the default resource file (usually in English).
- Resources.ru.resx — the file for the Russian language.
- Resources.de.resx — the file for the German language.
Inside each file, we will add string resources with the same names but different values:
Resources.resx (default language — en-US):
Name: GreetingValue: Hello, World!
Name: WelcomeMessageValue: Welcome to our application!Resources.ru.resx (Russian):
Name: GreetingValue: Привет, мир!
Name: WelcomeMessageValue: Добро пожаловать в наше приложение!Step 2: Accessing Resources in C# Code
.NET automatically generates a strongly typed class for accessing resources. Suppose the files are located in the project's Resources folder. Then access would look like this:
using System;using System.Globalization;using System.Threading;
class Program{ static void Main(string[] args) { // Set the culture for the current thread Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU"); Thread.CurrentThread.CurrentCulture = new CultureInfo("ru-RU");
// Get localized strings string greeting = Resources.Messages.Greeting; string welcome = Resources.Messages.WelcomeMessage;
Console.WriteLine(greeting); // Outputs: Привет, мир! Console.WriteLine(welcome); // Outputs: Добро пожаловать в наше приложение! }}Note: Resources.Messages is an auto-generated class based on the name of your RESX file (if the file is named Messages.resx).
Step 3: Localization in ASP.NET Core
In ASP.NET Core web applications, the process
Also in library
Working with ZIP Archives in PHP: ZipArchive and Compression Libraries
Kysely for TypeScript: Complete Guide with Examples
ErrorOr for C# (.NET): Complete Guide with Examples
HTML Parsing in C# (.NET): HtmlAgilityPack and AngleSharp Libraries
Rate Limiting in C# (.NET): Complete Guide to System.Threading.RateLimiting Library