Click here to Skip to main content
15,880,503 members
Articles / Web Development / ASP.NET

Localization in ASP.NET Core Web API

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
7 Feb 2022CPOL8 min read 37.6K   7   14
How to localize in ASP.NET Core Web API 6
In this tutorial, we will implement three steps to achieve ASP.NET Web API 6 localization, namely, apply localization configurations to the middleware, create needed resource files and finally, use IStringLocalizer to access the entries of the resource files.

Localization is a very important topic when you are planning to build an app or a site targeting multiple cultures and languages. You have to prepare your app or site to be ready to display all the information in accordance to the user’s relevant culture, this is very critical to achieve a wider range of audiences.

Imagine you are building an app, for an Arabic speaking country, but the main language of the app is in English. This way, your app won’t be useful for the larger proportion of your target market and you will significantly lose audience and thus your app will be forsaken with no returning users.

The more localized your content is, the better usability of your app or your site would be. You should always target full localization to guarantee frictionless interaction with your product.

In this tutorial, we will learn how to apply localization in ASP.NET Core Web API, by adding Arabic resource file. We will build the a RESTful API using the latest version of .NET 6 and Visual Studio 2022, therefore proceed to installing VS 2022 prior to continuing this tutorial. And finally, we will test the API using Postman.

Creating the Localization Project

Start Visual Studio 2022 and Create a new project – ASP.NET Core Web API

Image 1

Give it a name like ‘LocalizationInAspNetCoreWebApi’

Image 2

Then choose .NET 6 and press Create.

Image 3

As always, make sure to remove the template WeatherForecast controller and entity.

3 Steps of Localization in ASP.NET Core Web API

Now to apply localization to an ASP.NET Core Web API project, there are three major steps to follow:

  1. Including the localization into the API project middleware
  2. Adding the needed localization resource file
  3. Using the IStringLocalizer to access the resource file

Now let’s explain every step in detail while going through the tutorial.

1. Including the Localization into the APIs Middleware

We need to let the ASP.NET Core Web API know that we will be doing localization with specifying the options that Resources file path would be in the Resources folder that we will create later in this tutorial.

Therefore, let’s add the below code just after the CreateBuilder(args) call:

C#
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

Moreover, we have to inject the localization configurations into the APIs middleware to let it understand to which culture we are trying to localize to, of course, you can specify multiple locales if you are targeting two or more cultures in your localization.

In your program.cs file, let’s add the below code right after the builder.build() method call:

C#
var supportedCultures = new[] { "en-US", "ar" };
var localizationOptions =
    new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Here, we are saying that we will be supporting two cultures or locales which are “en-US” and “ar”, where the “en-US” will be the default if there is no instruction from the http request otherwise.

2. Adding the Needed Localization Resource File

In this tutorial, we will learn how to create and use resource files in ASP.NET Core Web API using two ways:

  • Using the Controller Resource Structure
  • Using the Shared Resource Structure

Let’s create a new folder under the project with name ‘Resources’.

We will use this folder to host all the .resx files in it.

Using the Controller Resource Structure

By using the controller resource structure, you can assign a resource file per Controller, which will allow you to structure and partition your resources over multiple files.

Before that, let’s make sure that we have the Controller created so that we can create the resource file that matches its name.

In your Controllers folder, add a new Controller with name PostsController, and make it an Empty API Controller:

Image 4

For now, let’s keep this controller. We will come back later to develop it so that it can read from the resource files.

In your Resources folder, right click and create a new folder with name ‘Controllers’, and inside this new ‘Controllers’ folder, create a new Resource with name ‘PostsController.ar.resx’.

Image 5

This will serve as the Arabic localization file for the posts controller. In ASP.NET Core, there is no need to add a localization file for the default locale or culture, this is because in the localized file you will have the name as the default and the value will be the localized value, if the StringLocalizer was not able to find the entry for a given string, then the string itself will be returned.

Furthermore, you won’t require to access the Resource file through other ways than the StringLocalizer.

Now back to our new resource file. Inside this file, let’s add some sample data to be able to test our work later on.

Image 6

Let’s see how the resource folder looks like:

Image 7

You can alternatively remove the Controllers folder from the Resources folder and rely on the Dot naming structure, so that resource file name will include the Controllers as a prefix like the below:

Resources\Controllers.PostsController.ar.resx

However, I prefer to use the folders structuring since it looks more organized and more readable.

Using the Shared Resource Structure

In this way, we can rely on a single file to have all the localization entries in it, so this file can be used among multiple controllers or other classes.

Let’s add a new resource file with name SharedResource.ar.resx.

Just to keep it simple, inside, we will add the same entries we added previously in the PostsController resource file:

Image 8

Now for this to work as an actually shared resource, we need to create a empty or dummy class with the same name ‘SharedResource’, and we should place it somewhere other than inside the Resources folder, we can create a new folder under the project with name Entities and place it there:

Image 9

C#
namespace LocalizationInAspNetCoreWebApi
{
    public class SharedResource
    {
    }
}

We have prepared the need localization files, in both ways, time now has come to see how can we use and access these resources from the controller.

3. Using the IStringLocalizer to Access the Resource File

The last step will be to access these resource files, this can happen in ASP.NET Core through the IStringLocalizer injected into the Controller through its constructor.

Let’s see the below code for the PostsController:

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

namespace LocalizationInAspNetCoreWebApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PostsController : ControllerBase
    {
        private readonly IStringLocalizer<PostsController> stringLocalizer;
        private readonly IStringLocalizer<SharedResource> sharedResourceLocalizer;

        public PostsController(IStringLocalizer<PostsController> postsControllerLocalizer,
                               IStringLocalizer<SharedResource> sharedResourceLocalizer)
        {
            this.stringLocalizer = postsControllerLocalizer;
            this.sharedResourceLocalizer = sharedResourceLocalizer;
        }

        /// <summary>
        /// This endpoint will access the PostsController
        /// Resource to retrieve the localized data ...
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("PostsControllerResource")]

        public IActionResult GetUsingPostsControllerResource()
        {
            var article = stringLocalizer["Article"];
            var postName = stringLocalizer.GetString("Welcome").Value ?? "";

            return Ok(new { PostType = article.Value, PostName = postName });
        }

        /// <summary>
        /// This endpoint will access the SharedResourece to retrieve the localized data ...
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("SharedResource")]
        public IActionResult GetUsingSharedResource()
        {
            var article = sharedResourceLocalizer["Article"];
            var postName = sharedResourceLocalizer.GetString("Welcome").Value ?? "";

            return Ok(new { PostType = article.Value, PostName = postName });
        }
    }
}

First, in the constructor, we are injecting two instances for the IStringLocalizer: one will be used to access the PostsController Resource file and the other instance will access the SharedResource file, notice the difference in the Type used for each instance.

Next, we have defined two endpoints to be able to showcase the access difference between the PostsController Resource versus the Shared Resource.

Furthermore, we are able to access the resource file entries through either using the key name of the dictionary or using the method GetString. Both are valid and return the same results.

In case the searched entry name does not exist in the resource dictionary, the stringLocalizer will return a flag of ResourceNotFound true.

Run the project and make sure the browser is showing Swagger documentation of your endpoints.

Image 10

Testing on Postman

Open Postman and create a new request, assign it to the url you have after you run the app along with the api/method route that you have and in the headers, add the Accept-Language header with the value as ‘ar’.

PostsController Resource – ar

Image 11

PostsController Resource – en

Image 12

Shared Resource – ar

Image 13

Shared Resource – en

Image 14

Adding the Content-Language in the Response Headers

One last thing to test, is to add the Content-Language to the response headers, this is mainly used to describe the content language of the response for the users.

Open program file, add the below line just before app.UseRequestLocalization(localizationOptions):

C#
localizationOptions.ApplyCurrentCultureToResponseHeaders = true;

Run your API again, and toggle back to Postman.

Try to call one of the API requests:

Image 15

Notice once the endpoint returns the result, in the Headers tab of the Response part, you will see a new header with name Content-Language with value ‘ar’ , this means that the content returned is in ar locale.

Summary

In this tutorial, we learned how to localize in ASP.NET Core Web API 6. We implemented three steps to achieve the localization: applying the localization configurations to the middleware, creating the needed resource files and lastly, using the IStringLocalizer to access the entries of the resource files.

Also, we learned that there are two ways to add the resource files for Controllers: Controller structure Resource and Shared Resource, based on the fact that in the tutorial, we implement both strategies and created two endpoints to access the resource for each resource file.

Eventually, we managed to test all our use cases, using Postman, and tested as well applying the Content-Language header for the responses so that we can broadcast or tell the users that the response is returned in the requested locale.

Localization should be done on multiple layers; On UI, you should make sure to localize all the labels, placeholders, titles, front-end validation messages, etc. Then, on the API side, you have to make sure that you return the proper exceptions with code and message so that the UI can translate the code into a localized message on the UI. Also, your API should define resource files with the intended localization for any needed translation strings and finally, you should keep separate tables for localized fixed or less frequently changing content such as countries, cities, categories, types, etc.

And if you are working on a huge product, you might need to consult with professional copywriters or marketing specialists to advise and provide you with the best localization strategies for your target cultures, and prepare culturally accurate localized texts and wordings that would appear native and seamlessly understood by your targeted users.

References

You can find the code in my GitHub account.

For further information about localization in ASP.NET Core, you can check Microsoft’s Official Documentation.

For further reading about localization in general, you can check this article.

Bonus

Enjoy the poetic tunes of the piano genius “Chopin” – Waltz Op.69 No.2, played by Vladimir Ashkenazy

The post Localization in ASP.NET Core Web API appeared first on Coding Sonata.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Jordan Jordan
A passionate software developer with 13+ years of overall experience in various development languages including C#/vb.net, java. The technologies I mostly focus on are: ASP.NET Core, Android, Angular

I currently work as a Corporate Technical Manager in the Digital Solutions Team at Aramex International in Amman, Jordan.

Comments and Discussions

 
GeneralMy vote of 5 Pin
MSI-9015-Mar-24 19:30
MSI-9015-Mar-24 19:30 
QuestionRequest for help in localization implementation in ASP.Net core project Pin
Karnika 202322-Sep-23 3:36
Karnika 202322-Sep-23 3:36 
QuestionResx files after deployment Pin
Dimitris Karvelis27-Jul-23 14:06
Dimitris Karvelis27-Jul-23 14:06 
QuestionLocalizing default .NET Core messages Pin
Jaime Stuardo - Chile15-Dec-22 2:36
Jaime Stuardo - Chile15-Dec-22 2:36 
PraiseAwesome, thanks Aram Pin
NaseemHajoj9-Oct-22 1:58
NaseemHajoj9-Oct-22 1:58 
GeneralRe: Awesome, thanks Aram Pin
Aram Tchekrekjian17-Oct-22 2:00
Aram Tchekrekjian17-Oct-22 2:00 
QuestionLocalizing WPF application Pin
Ned Ganchovski8-Feb-22 3:10
professionalNed Ganchovski8-Feb-22 3:10 
AnswerRe: Localizing WPF application Pin
Aram Tchekrekjian11-Feb-22 13:26
Aram Tchekrekjian11-Feb-22 13:26 
GeneralRe: Localizing WPF application Pin
Ned Ganchovski12-Feb-22 6:41
professionalNed Ganchovski12-Feb-22 6:41 
Question.Net MAUI Localization Pin
LooWooL8-Feb-22 1:20
professionalLooWooL8-Feb-22 1:20 
AnswerRe: .Net MAUI Localization Pin
Aram Tchekrekjian11-Feb-22 12:55
Aram Tchekrekjian11-Feb-22 12:55 
GeneralOne use case to consider Pin
ahmad_5118-Feb-22 1:13
professionalahmad_5118-Feb-22 1:13 
GeneralRe: One use case to consider Pin
Aram Tchekrekjian11-Feb-22 12:40
Aram Tchekrekjian11-Feb-22 12:40 
Hello Ahmad,

Thank you for your message and apologies for the late reply. The Accept-Language Header is not the only way you can use to set the API culture or locale. In fact, there are 2 other ways that can be used for this purpose, one of them is through query strings. If you add the culture and/or culture-ui parameters to the URL, the QueryStringRequestCultureProvider will interpret these parameters and set the culture of your API with the provided values.

So in our tutorial, if we pass the culture as 'ar' in the query strings, like this: https://localhost:7153/api/posts/SharedResource?culture=ar and keep sending the Accept-Language as 'en', then you will get the result in Arabic, because the priority will go to the query string parameters.

I hope this answers your question.
GeneralRe: One use case to consider Pin
ahmad_51111-Feb-22 20:07
professionalahmad_51111-Feb-22 20:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.