Globalization And Localization In .NET Core

Introduction

A multilingual website allows the site to be accessed by a wider audience with different language and cultural preferences. .NET Core provides services and middleware for localization into various languages and cultures.

What is Globalization?

Globalization is the process of designing applications that can handle different cultures. By adding support for input, display, and output in specific languages related to specific geographical areas, globalization makes it easier for people from around the world to use these apps.

What is Localization?

Localization is the process of translating content to match the specific needs of a certain culture or language. This includes transcribing text, as well as formatting numbers, dates and times, using different currencies, and employing various symbols.

Read the Official Documentation from Microsoft here.

In this tutorial, I am using .NET Core 7.0.

Prerequisites

  1. Visual Studio 2022
  2. ASP.NET and web development tools installed

Getting Started

First off, let's create a new ASP.NET Core MVC project in Visual Studio as mentioned below,

To create a new ASP.NET Core 7.0 MVC project in Visual Studio 2022, follow the steps outlined below.

  1. Start Visual Studio 2022 IDE.
  2. Click on the “Create new project” option.
  3. In the next screen, select “ASP.Net Core Web MVC Application” from the list of templates displayed.
  4. Click Next.
  5. Specify the name and location of your project in the “Configure your new project” screen.
  6. In the “Create a New ASP.NET Core Web Application” screen, select .NET Core as the runtime and ASP.NET Core 7.0 (or later) from the drop-down list at the top.
  7. Select “Web Application (Model-View-Controller)” as the project template to create a new ASP.NET Core MVC application.
  8. Uncheck “Enable Docker Support” and “Configure for HTTPS.” You won't be using either of these here.
  9. Specify authentication as “No Authentication.” You won't be using authentication here either.
  10. Click Create to complete the process.

Creating Language Service

Add a Language Service class as mentioned below,

using Microsoft.Extensions.Localization;
using System.Reflection;
namespace Localization.Services {
    /// <summary>
    /// Dummy class to group shared resources
    /// </summary>
    public class SharedResource {}
    public class LanguageService {
        private readonly IStringLocalizer _localizer;
        public LanguageService(IStringLocalizerFactory factory) {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create("SharedResource", assemblyName.Name); // §REVIEW_DJE: "SharedResource" or "ShareResource"
        }
        public LocalizedString Getkey(string key) {
            return _localizer[key];
        }
    }
}

Configuring Localization into our application

It should be noted that localization in ASP.NET Core is an opt-in feature and is not enabled by default. The ASP.NET Core framework provides a middleware that is meant for localization. You can add this middleware to the request processing pipeline by calling the UseRequestLocalization method.

There are three methods used to configure localization in ASP.NET Core. These include the following,

  • AddDataAnnotationsLocalization: This method is used to provide support for DataAnnotations validation messages.
  • AddLocalization: This method is used to add localization services to the services container.
  • AddViewLocalization: This method is used to provide support for localized views.

Define the Allowed Cultures

In .NET, you can take advantage of the CultureInfo class for storing culture-specific information. You should now specify the languages and cultures that you would like your application to provide support for. To do this, create a list of type CultureInfo to store the supported cultures, as shown below.

Register localization in service section in program.cs file as mentioned below in Localization Region,

using Localization.Services;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Options;
using System.Globalization;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
#region Localization
//Step 1
builder.Services.AddSingleton < LanguageService > ();
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc().AddViewLocalization().AddDataAnnotationsLocalization(options => {
    options.DataAnnotationLocalizerProvider = (type, factory) => {
        var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
        return factory.Create("ShareResource", assemblyName.Name);
    };
});
builder.Services.Configure < RequestLocalizationOptions > (options => {
    var supportedCultures = new List < CultureInfo > {
        new CultureInfo("fr-FR"),
        new CultureInfo("en-US")
    };
    options.DefaultRequestCulture = new RequestCulture(culture: "fr-FR", uiCulture: "fr-FR");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    options.RequestCultureProviders.Insert(0, new QueryStringRequestCultureProvider());
});
#endregion
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) {
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
//Step 2
app.UseRequestLocalization(app.Services.GetRequiredService < IOptions < RequestLocalizationOptions >> ().Value);
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

Create Resource Files for Each Locale

Create Resource Folder and add two files in it one with en-US and another fr-FR as shown below

Add a ChangeLanguage method in controller as mentioned below,

#region Localization
public IActionResult ChangeLanguage(string culture) {
    Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), new CookieOptions() {
        Expires = DateTimeOffset.UtcNow.AddYears(1)
    });
    return Redirect(Request.Headers["Referer"].ToString());
}
#endregion

Add a dropdown in _layout.cshtml for the change language option as mentioned below

<div class="dropdown">
  <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown"> Localization </button>
  <ul class="dropdown-menu">
    <li>
      <a asp-controller="Home" asp-action="ChangeLanguage" asp-route-culture="en-US" class="dropdown-item">
        <i class="flag-icon flag-icon-gb"></i> English </a>
    </li>
    <li>
      <a asp-controller="Home" asp-action="ChangeLanguage" asp-route-culture="fr-FR" class="dropdown-item">
        <i class="flag-icon flag-icon-gb"></i> French </a>
    </li>
  </ul>
</div>

Accessing a Localized String in your Controller,

using Localization.Models;
using Localization.Services;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace Localization.Controllers {
    public class HomeController: Controller {
        private readonly ILogger < HomeController > _logger;
        private LanguageService _localization;
        public HomeController(ILogger < HomeController > logger, LanguageService localization) {
            _localization = localization;
            _logger = logger;
        }
        public IActionResult Index() {
            ViewBag.WelcomeMessage = _localization.Getkey("str_welcome_message");
            //get culture information
            var currentCulture = Thread.CurrentThread.CurrentUICulture.Name;
            return View();
        }
        #region Localization
        public IActionResult ChangeLanguage(string culture) {
            Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), new CookieOptions() {
                Expires = DateTimeOffset.UtcNow.AddYears(1)
            });
            return Redirect(Request.Headers["Referer"].ToString());
        }
        #endregion
        public IActionResult Privacy() {
                return View();
            }
            [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error() {
            return View(new ErrorViewModel {
                RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
            });
        }
    }
}

Using Localization in Views

Step 7

Under _ViewImports.cshtml inject the language service so that we can access the Language service in our view.

@using Localization
@using Localization.Models
@using Localization.Services;
@inject LanguageService _localization
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Step 8

Access the localization in your view.

 @_localization.Getkey("str_welcome_message")

GIT SOURCE CODE

I would greatly appreciate it if you would support me if have you enjoyed this post and found it useful. Thank you in advance.