How To Use Localization In ASP.NET Core - Day Ten

In the previous article of this series, we discussed web socket implementation in .NET Core application. Now, in this article, we will discuss how we can use globalization and localization in the ASP.NET Core application.

If you want to look at the previous articles of thse series, please visit the links given below.

English is not the first language for a sizable population of the world; therefore building a website that just renders in English may not be a very wise idea. Imagine, with just some content localization, how much we can gain in terms of application reach. Internationalization is all about designing our application so that anyone in any region of the world can use the application in their native language. Internationalization involves Globalization and Localization. Globalization is the process of designing apps that support different cultures. Globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas. Actually localization is one of the processes of adapting a globalized application, which we have already processed for localization to a particular country or culture/locale. Basically application localization involves the following key functionalities,

  1. Make the application's content localizable
  2. Provide localized resources for the languages and cultures which we support
  3. Implement a strategy to select the language/culture for each request or each page

How Localization Implemented in Application

ASP.NET Core introduced two interfaces namely IStringLocalizer and IStringLocalizer<T> for implementing or developing localized applications. IStringLocalizer interface uses the ResourceManager and ResourceReader to provide user defined culture-specific resources at run time. This simple interface contains an indexer and an IEnumerable for returning localized strings to the application. IStringLocalizer doesn't require we to store the default language strings in a resource file. We can develop an application which developed for localization and not need to create resource files at the beginning of development. The code below shows how to wrap the string "Hello World" for localization.

  1. using Microsoft.AspNetCore.Mvc;  
  2. using Microsoft.Extensions.Localization;  
  3. namespace Localization.StarterWeb.Controllers  
  4. {  
  5.    [Route("api/[controller]")]  
  6.    public class HelloController : Controller  
  7.    {  
  8.       private readonly IStringLocalizer<HelloController> _localizer;  
  9.       public HelloController(IStringLocalizer<HelloController> localizer)  
  10.       {  
  11.          _localizer = localizer;  
  12.       }  
  13.       [HttpGet]  
  14.       public string Get()  
  15.       {  
  16.          return _localizer["Hello World"];  
  17.       }  
  18.    }  
  19. }  

In the above code sample, the IStringLocalizer<T> implementation comes by using Dependency Injection. If the localized value of "Hello World" is not found, then the indexer key is returned, that is, the string "Hello World". We can leave the default language message strings in the application and use them in the localizer, so that we can focus on developing the application. For this purpose, we can use the IHtmlLocalizer<T> implementation for resources that contain HTML. Actually IHtmlLocalizer HTML encodes arguments that are formatted in the resource string, but not the resource string. In the sample highlighted below, only the value of name parameter is HTML encoded.

  1. using System;  
  2. using Microsoft.AspNetCore.Http;  
  3. using Microsoft.AspNetCore.Localization;  
  4. using Microsoft.AspNetCore.Mvc;  
  5. using Microsoft.AspNetCore.Mvc.Localization;  
  6. namespace Localization.StarterWeb.Controllers  
  7. {  
  8.    public class EmployeeController : Controller  
  9.    {  
  10.       private readonly IHtmlLocalizer<EmployeeController> _localizer;  
  11.       public EmployeeController(IHtmlLocalizer<EmployeeController> localizer)  
  12.       {  
  13.          _localizer = localizer;  
  14.       }  
  15.       public IActionResult Hello(string name)  
  16.       {  
  17.          ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];  
  18.          return View();  
  19.       }  
  20.       …   
  21.     }  
  22. }  

Localization in the View Page in Application

If we want to implement localization in the view of our application, then we need to use IViewLocalizer interface. Basically IViewLocalizer interface service provides localized strings for a view. Actually ViewLocalizer class implements this interface and finds the resource location for the localized string from the view file path. The following code shows how to use the default implementation of IViewLocalizer :

  1. @using Microsoft.AspNetCore.Mvc.Localization  
  2. @inject IViewLocalizer Localizer  
  3. @{  
  4.    ViewData["Title"] = Localizer["AboutMe"];  
  5. }  
  6. <h2>@ViewData["Title"].</h2>  
  7. <h3>@ViewData["Message"]</h3>  
  8. <p>@Localizer["Use this area to provide extra information."]</p>  

The actual implementation of IViewLocalizer basically depends on view’s file name which means it finds the resource file based on the view's file name. That means there is no option to use a global shared resource file in the application for the view. ViewLocalizer implements the localizer using IHtmlLocalizer , so Razor doesn't need HTML encoder for the localized string. So we can parameterize resource strings and IViewLocalizer will encode the parameters, but not the resource string. Consider the following Razor markup:

  1. @Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]  

View localization requires the "Localization.AspNetCore.TagHelpers" NuGet package.

DataAnnotations localization for Validation Purpose

For implementing localization string to display DataAnnotations error messages, we can develop the same with the help of IStringLocalizer<T> . Using this option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in the resource file.

  1. public class RegisterViewModel  
  2. {  
  3.    [Required(ErrorMessage = "The Email field is required.")]  
  4.    [EmailAddress(ErrorMessage = "The Email field is not a valid e-mail address.")]  
  5.    [Display(Name = "Email")]  
  6.    public string Email { getset; }  
  7.    [Required(ErrorMessage = "The Password field is required.")]  
  8.    [StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]  
  9.    [DataType(DataType.Password)]  
  10.    [Display(Name = "Password")]  
  11.    public string Password { getset; }  
  12.    [DataType(DataType.Password)]  
  13.    [Display(Name = "Confirm password")]  
  14.    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]  
  15.    public string ConfirmPassword { getset; }  
  16. }  

Working with Resource File

A resource file is a useful mechanism for separating localizable strings from code. Translated strings for the non-default language are isolated .resx resource files. For example, you might want to create German resource file named containing translated strings. "de" is the language code for Spanish. To create this resource file in Visual Studio:

  1. In Solution Explorer, right click on the folder which will contain the resource file > Add > New Item.

  2. In the "Search installed templates" box, enter "resource" and name the file.

  3. Enter the key value (native string) in the Name column and the translated string in the Value column.

You can read the next part here,