π How to Add Multiple Languages to Your ASP.NET Core Application (Step-by-Step Localization Guide)
Do you want your ASP.NET Core application to work in multiple languages? In this guide, you will learn how to do it from scratch using the globalization and localization features built into .NET.
You will see how to translate texts, validation messages, and allow users to change the language from the interface.
π§ What is Localization in .NET?
Localization means adapting your application to different languages and cultures. This involves translating:
- Interface texts (e.g., βHello worldβ or βSubmitβ)
- Error and validation messages
- Dates, numbers, currencies, etc.
.NET allows you to organize these translations using special files called .resx, and apply them automatically.
β Prerequisites
- Install .NET 6 or later.
- Basic knowledge of ASP.NET Core MVC.
- Visual Studio or VS Code (with the C# extension).
π Step 1 β Create the Project
Open your terminal or Visual Studio and create a new project:
dotnet new mvc -n LocalisationDemo
cd LocalisationDemo
This project will be a simple web application with multilingual support.
π¦ Step 2 β Configure Localization Services
Open Program.cs
and add these lines:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddControllersWithViews()
.AddViewLocalization()
.AddDataAnnotationsLocalization();
This tells .NET to use resource files (.resx
) in a folder called Resources
to manage translations.
π Step 3 β Support for Multiple Languages
In Program.cs
, add this configuration:
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en"),
new CultureInfo("es"),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture("en");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
// Use cookies to remember the user's selected language
options.RequestCultureProviders.Insert(0, new CookieRequestCultureProvider());
});
Then, activate this configuration before the routing middleware:
var locOptions = app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
π Step 4 β Create Translation Files (.resx)
Create a folder called Resources
.
Inside, create these files:
SharedResources.resx
β default (English)SharedResources.es.resx
β SpanishSharedResources.fr.resx
β French
Each file will contain the same keys but with different texts. For example:
SharedResources.resx
<data name="Greeting">
<value>Hello World!</value>
</data>
SharedResources.es.resx
<data name="Greeting">
<value>Β‘Hola Mundo!</value>
</data>
SharedResources.fr.resx
<data name="Greeting">
<value>Bonjour le monde!</value>
</data>
You can also translate validation messages:
<data name="RequiredField">
<value>This field is required.</value>
</data>
π Step 5 β Create the SharedResources Class
This class serves as a reference for localization:
namespace LocalisationDemo
{
public class SharedResources
{
}
}
π¨βπ« Step 6 β Use Translated Texts in the Controller
In HomeController.cs
:
private readonly IStringLocalizer<SharedResources> _localizer;
public HomeController(IStringLocalizer<SharedResources> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
ViewBag.Message = _localizer["Greeting"];
return View();
}
π Step 7 β Create a Language Selector
In the Index.cshtml
view:
@using System.Globalization
@{
var currentCulture = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
}
<h1>@ViewBag.Message</h1>
<form method="post" asp-controller="Home" asp-action="SetLanguage">
<label>Choose language:</label>
<select name="culture" onchange="this.form.submit()">
<option value="en" selected="@(currentCulture == "en" ? "selected" : null)">English</option>
<option value="es" selected="@(currentCulture == "es" ? "selected" : null)">EspaΓ±ol</option>
<option value="fr" selected="@(currentCulture == "fr" ? "selected" : null)">FranΓ§ais</option>
</select>
</form>
And in the controller:
[HttpPost]
public IActionResult SetLanguage(string culture)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return RedirectToAction("Index");
}
This saves the selected language in a cookie and keeps the dropdown in sync with the current culture.
π§ͺ Step 8 β Translate Validation Messages
Create a model with a validation message:
public class DummyModel
{
[Required(ErrorMessage = "RequiredField")]
public string Name { get; set; }
}
.NET will look for the translation of "RequiredField"
in the .resx
files.
π Final Result
You now have an application that:
β Displays translated texts β Changes the language from the interface β Remembers the selected language across sessions β Translates validation messages β Keeps the selected option in the dropdown correctly highlighted