web analytics

Implementing Globalization and localization in ASP.NET Core Application

Options

codeling 1595 - 6639
@2020-11-28 13:45:11

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.
  • Localization is the process of adapting a globalized app, which you have already processed for localizability, to a particular culture/locale. 

App localization involves the following:

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

To support creating a multilingual ASP.NET Core application, ASP.NET Core provides services and middleware for localizing into different languages and cultures.

@2020-11-28 14:46:31

IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time. The simple interface has an indexer and an IEnumerable for returning localized strings. 

IStringLocalizerFactory represents a factory that creates IStringLocalizer instances.

@2020-11-28 15:34:29

Register services and configure middleware

Startup.ConfigureServices method:

//Assume all resources are in the folder named "resources" in the website

services.AddLocalization(location => { location.ResourcesPath = "Resources"; });

services.AddSingleton<IStringLocalizerFactory, ResourceManagerStringLocalizerFactory>();

services.Configure<RequestLocalizationOptions>(
   options =>
   {
       var supportedCultures = new List<CultureInfo>
           {
                new CultureInfo("en-CA"),
                new CultureInfo("fr-CA")
           };

       //options.DefaultRequestCulture = new RequestCulture(culture: "en-CA");
       options.DefaultRequestCulture = new RequestCulture(culture: "en-CA", uiCulture: "en-CA");
       options.SupportedCultures = supportedCultures;
       options.SupportedUICultures = supportedCultures;

       //options.RequestCultureProviders.Insert(0, new QueryStringRequestCultureProvider());
       //options.RequestCultureProviders = new List<IRequestCultureProvider>
       //     {
       //         new QueryStringRequestCultureProvider(),
       //         new CookieRequestCultureProvider()
       //     };
   });

The current culture on a request is set in the localization middleware. The localization middleware is enabled in the Configure method of Startup.cs file.

app.UseRequestLocalization();

//var localizationOption = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
//app.UseRequestLocalization(localizationOption.Value);

then UseRequestLocalization initializes a RequestLocalizationOptions object. This should be placed at least before your UseMvc call.

Create resources

 

Inject the services

IStringLocalizer<T> and/or IStringLocalizerFactory implementation can be injected in the controller constructor through Dependency Injection:

private readonly ILogger<HomeController> _logger;
private readonly IStringLocalizer _controllerLocalizer;
private readonly IStringLocalizer _sharedLocalizer;

public HomeController(ILogger<HomeController> logger, IStringLocalizer<HomeController> localizer, IStringLocalizerFactory factory)
{
    _logger = logger;

    _controllerLocalizer = localizer;

    var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
    _sharedLocalizer = factory.Create("SharedResource", assemblyName.Name);

}

 

The code above demonstrates each of the two factory create methods.

You can partition your localized strings by controller, area, or have just one container. In the sample app, a dummy class named SharedResource is used for shared resources.

// Dummy class to group shared resources

public class SharedResource
{
}

To fully control the access to the resource, you can inject an IStringLocalizerFactory into the controller or view.

Use the service

public IActionResult Index()
{
    ViewData["HelloWorldFromControllerReource"] = _controllerLocalizer["HelloWorld"];
    ViewData["HelloWorldFromSharedResource"] = _sharedLocalizer["HelloWorld"];

    return View();
}

 

Change Culture

[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new     RequestCulture(culture)),
    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
    );

    return LocalRedirect(returnUrl);
}

Get the current language

var currentLanguage = HttpContext.Features.Get<IRequestCultureFeature>().RequestCulture.Culture.Name;

@2020-12-06 22:14:24

IStringLocalizer doesn't require storing the default language strings in a resource file. You can develop an app targeted for localization and not need to create resource files early in development. The code below shows how to wrap the string "About Title" for localization.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Localization.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get()
        {
            return _localizer["About Title"];
        }
    }
}

If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "About Title". You can leave the default language literal strings in the app and wrap them in the localizer, so that you can focus on developing the app. You develop your app with your default language and prepare it for the localization step without first creating a default resource file. Alternatively, you can use the traditional approach and provide a key to retrieve the default language string. For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an app. Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com