Asp.Net Core Globalization Example

Nowadays all web application are built for multiple geography, where we expect visitors from different culture, to make the application more local to them we need to create different type to content for different region, and that’s where globalization and localization in Asp.net Core framework is helpful.

In this tutorial you will learn how to implement Globalization and Localization in Asp.Net Core application.

What is Globalization?

Asp.net Core Globalization is the process of making a globalised web application, which means there will be different content for different geography, means localised content.

What is Localization?

Localization is the process of setting up content for local geography, continuation process of globalization.

Asp.net core provides mechanism of adding local culture info into middleware

using Microsoft.AspNetCore.Localization;
using System.Globalization;
IList<CultureInfo> supportedCultures = new List<CultureInfo>
{
    new CultureInfo("en-US"),
    new CultureInfo("fi-FI"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("en-US"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
});

Localization in Asp.net Core application

To setup localization in controller you need to add following code.

Things to notice

  • Required namespace
  • Dependency Injection through constructor
  • Using the instance of IStringLocalizer

Note:
Like earlier version of Asp.net we still can use resource file (.resx) to store localization information in the form of key-value pair, but now in asp.net core we can store localization information in Json file (.json) too, the disadvantage of keeping information in resx file is, that every time we add a new key, we need to compile the assembly for that key to get reflected, on the other hand using JSON file we can add any key and use them in razor view without compiling the whole assembly again.

Controller Setup

Here is how localization can be implemented in controller level, also have a provision to change the current culture by user from UI through query string

using Microsoft.Extensions.Localization;
using Microsoft.AspNetCore.Mvc;
using System.Globalization;
public class welcomeController : Controller
{
private readonly IStringLocalizer<welcomeController> _localizer;
       
    public welcomeController(IStringLocalizer<welcomeController> localizer)
    {
        _localizer = localizer;
    }
    public IActionResult index()
    {
        return View();
    }
    public IActionResult hello()
    {
        string currentCulture = Request.Query["culture"];
        if (!string.IsNullOrEmpty(currentCulture))
        {
            CultureInfo.CurrentCulture = new CultureInfo(currentCulture);
        }
        ViewData["WelcomeMessage"] = _localizer["WelcomeMessage"];
        return View();
    }
}

Implement Localization Step by Step

Here is the complete localization implementation with working code (you can straight away use the code in your project)

Step 1

Right click on your project then "Manage NuGet Packages", and then add following two packages in your solution

Microsoft.AspNetCore.Localization
Microsoft.AspNetCore.Localization.Routing

Install NuGet package "Askmethat.Aspnet.JsonLocalizer"

Step 2

Open your Startup.cs file and add following code in "ConfigureServices" method.

public void ConfigureServices(IServiceCollection services)
{
    #region Localization
    services.AddSingleton<IdentityLocalizationService>();             
    services.AddLocalization(o =>
    {
        // We will put our translations in a folder called Resources
        o.ResourcesPath = "Resources";
    });
    services.AddSingleton<IStringLocalizerFactory, JsonStringLocalizerFactory>();
    services.AddSingleton<IStringLocalizer, JsonStringLocalizer>();
    services.AddMvc()
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, 
        opts => { opts.ResourcesPath = "Resources"; })
    .AddDataAnnotationsLocalization(options =>
    {
     });
    CultureInfo.CurrentCulture = new CultureInfo("en-US");
    #endregion 
}

Notice how default culture has been set using CultureInfo.CurrentCulture

Now add the following code in "Configure" method of same startup.cs file

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
#region Localization
	IList<CultureInfo> supportedCultures = new List<CultureInfo>
	{
		new CultureInfo("en-US"),
		new CultureInfo("en-IN"),
		new CultureInfo("fr-FR"),
	};            
	var localizationOptions = new RequestLocalizationOptions
	{
		DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"),
		SupportedCultures = supportedCultures,
		SupportedUICultures = supportedCultures                
	};
	app.UseRequestLocalization(localizationOptions);
   
	var requestProvider = new RouteDataRequestCultureProvider();
	localizationOptions.RequestCultureProviders.Insert(0, requestProvider);
	var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
	app.UseRequestLocalization(locOptions.Value);
            
#endregion
}
Step 3

You need to write following custom classes for localization in Json format. Let's create a class with name "JsonLocalization"

using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
namespace WebTrainingRoom
{
    class JsonLocalization
    {
        public string Key { get; set; }
        public Dictionary<string, string> LocalizedValue = new Dictionary<string, string>();
    }
    public class JsonStringLocalizerFactory : IStringLocalizerFactory
    {
        public IStringLocalizer Create(Type resourceSource)
        {
            return new JsonStringLocalizer();
        }
        public IStringLocalizer Create(string baseName, string location)
        {
            return new JsonStringLocalizer();
        }
    }
    public class JsonStringLocalizer : IStringLocalizer
    {
        List<JsonLocalization> localization = new List<JsonLocalization>();
        public JsonStringLocalizer()
        {
            //read all json file
            JsonSerializer serializer = new JsonSerializer();
            localization = JsonConvert.DeserializeObject<List<JsonLocalization>>(File.ReadAllText(@"Resources/localization.json"));
        }
        public LocalizedString this[string name]
        {
            get
            {
                var value = GetString(name);
                return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
            }
        }
        public LocalizedString this[string name, params object[] arguments]
        {
            get
            {
                var format = GetString(name);
                var value = string.Format(format ?? name, arguments);
                return new LocalizedString(name, value, resourceNotFound: format == null);
            }
        }
        public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
        {
            return localization.Where(l => l.LocalizedValue.Keys.Any(lv => lv == CultureInfo.CurrentCulture.Name)).Select(l => new LocalizedString(l.Key, l.LocalizedValue[CultureInfo.CurrentCulture.Name], true));
        }
        public IStringLocalizer WithCulture(CultureInfo culture)
        {
            return new JsonStringLocalizer();
        }
        private string GetString(string name)
        {
            var query = localization.Where(l => l.LocalizedValue.Keys.Any(lv => lv == CultureInfo.CurrentCulture.Name));
            var value = query.FirstOrDefault(l => l.Key == name);
            return value.LocalizedValue[CultureInfo.CurrentCulture.Name];
        }
    }
}

Notice in above code, we have specified the json file location at File.ReadAllText(@"Resources/localization.json"). Means in root of the application there is a folder called “Resources” , then there is a file called "localization.json"

Step 4

Now create a class with name “IdentityLocalizationService”. Now create a class with name “IdentityLocalizationService”, in this class we have methods that will allow us to access localized string based on key

using Microsoft.Extensions.Localization;
using System.Reflection;
namespace WebTrainingRoom.Resources
{
    public class IdentityLocalizationService
    {
        private readonly IStringLocalizer _localizer;
        public IdentityLocalizationService(IStringLocalizerFactory factory)
        {
            var type = typeof(IdentityResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create("IdentityResource", assemblyName.Name);
        }
        public LocalizedString GetLocalizedHtmlString(string key)
        {
            return _localizer[key];
        }
        public LocalizedString GetLocalizedHtmlString(string key, string parameter)
        {
            return _localizer[key, parameter];
        }
    }
    public class IdentityResource
    {
    }
     
}
Step 5

If you want multiple-localization to be implemented, then you need to add multiple json file with same key values.

en-US.json
{
  "WelcomeMessage": "Welcome to my World."  
}
en-IN.json
{
  "WelcomeMessage": "Namaskar! Apne Ghar Ayyea"
}

You also can write all in one json file

[
  {
    "Key": "WelcomeMessage",
    "LocalizedValue" : {
      "fr-FR": "Bienvenue dans mon monde.",
      "en-US": "Welcome to my Home.",
      "en-IN": "Swagatam! Apne Ghar Ayyea."
    }
  }
]

How to change current culture

You may need to provide an option of changing current culture to your web page visitor, so in case they want to change the current culture, they can easily switch to their native culture

Changing current culture in asp.net core application is very easy

CultureInfo.CurrentCulture = new CultureInfo("en-IN");
string currentCulture = Request.Query["culture"];
if (!string.IsNullOrEmpty(currentCulture))
    CultureInfo.CurrentCulture = new CultureInfo(currentCulture);
How to get the list of all CultureInfo

Here are few lines of code can get you the list of all culture info, so you can set the right culture for your required geography, remember you need to use the right culture name; otherwise it may get you error.

using System;
using System.Globalization;
using System.Collections.Generic;
List<string> list = new List<string>();
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{        
    list.Add(String.Format("{0} / {1}", ci.Name, ci.EnglishName));       
}
list.Sort();  // sort by name
Asp.Net Core C# Examples | Join Asp.Net MVC Course