In this article, we will go through a less-talked about topic in the ASP.NET Core Community. We will discuss in detail, Globalization and Localization in ASP.NET Core Application and go through various approaches on changing the Culture of the Application via Request. We will also do some advanced configuration where we store the Selected Language Information to the Cookie in the client browser. You can see the complete source code of this implementation on my Github.
While starting to build an ASP.NET Core application, or any other application, There are few considerations to take care of. One of them is, āWill our Application be Multi-Lingual?ā. According to me, it is highly important to make your application Multi-Lingual, if you are not able to anticipate the future of your application. Down the line, there can be an instance where you have already completed the application, but suddenly it needs to be multilingual as well. Trust me, you do not want to be in that place.
To be on the safer side, itās good to build your applicaiton with multi-language support right from the beginning, yeah?
What weāll Learn?
In brief, here are the topics that we will cover in this article.
- Basics of Globalization & Localization
- Building a MultiLingual ASP.NET Core Application (Web-API and MVC)
Here is a small demo of what we will build.
What is Globalization?
Globalization is a process by which develoeprs make a product supported in multiple languages. This mostly involves improving the backend of web applications, which ultimately contributes to the SEO of the website. This includes meta-data, file names, labels and even the website URLs.
What is Localization?
Localization is the process to transalate the content to fulfil the demands of a particular culture / language. This does not limit to just transalting the texts, but also numbers, date and time formats, currency , symbols and so on.
Read the Official Documentation from Microsoft here.
Building a Multi-Lingual ASP.NET Core Application
We will build an ASP.NET Core MVC Application and try to implement Localization to it. I wil be using Visual Studio 2019 as my IDE. So in this application, for better demonstration of the implementation, we will work with both Views and API Controllers. In the Views, we will localize the Content of the UI and in the API part, letās work on the messages thrown by the API.
We will be working with Resource files to store the transalations for various languages. Letās create a new ASP.NET Core 3.1 MVC Application.
PS, Selecting Authentication is Optional.
Registering the Required Services and Middleware
Letās register the Service required for Localization in our ASP.NET Core Applicaiton. Navigate to Startup.cs/ConfigureServices method.
Now, letās add the Localization Middleware to the HTTP Pipeline. Navigate to Configure Method of Startup.cs and add in the following.
Line 1 - Here, we specify the Cultures that our Application will support. For now, it supports English and French. You could make it more specific by adding something like āen-USā and āfr-FRā. In this line we define a collection of supported cultures for later use.
Line 5 - Everytime your Application getās a request, How will the application know which culture to use? Here is where we define it.
Line 6 - If the request contains no culture information or cultures that we donāt yet support, the user will be served with English Resources.
Line 7 - This will indicate how we format numbers, currencies etc.
Line 8 - Used when we retrieve resources.
Localizing the API Endpoint.
Once we have registered the required services and middlewares, letās try to use Localization in an API endpoint. In this section, we will create a Random API endpoioint that generates a GUID with a message, and try to switch languages between English and French. We will also go through 2 of the 3 ways to switch locales for the incoming request.
Create a New Folder in the Controllers and name it API. Here, add a new Empty API Controller and name it LanguageController.
Line 11 - IStringLocalizer is used to generate Localized String based on the key. Here we are going to inject this Service to the constructor of the Controller.
Line 19 - Random GUID Generation.
Line 20 - We use the Localizer Object to get the appropriate message that has a Key āRandomGUIDā in our Resource File. You can see that we are also passing the GUID to the object. But we have not yet created a Resource File right?
Resource File Naming and Folder Convention.
This is one of the cleaner approaches by Microsoft. Ideally Resources for each View/API Controller/Models has to seperated with a smiliar folder structure.
In our case, the Language Controller is located at Controllers/API/LanguageController.cs. Remeber the Resource Folder we created in the beginning? Here is where you would place the Resources. Create a similar folder structure within the Resource Folder.
Understand the convention? We need resources for the Language Controller, hence we split the LanguageController to both en and fr resource files having corresponding resources.
RandomGUID is the key that we specified in the API Controller right? Letās add values to this particular key in both of the Resource Files.
Get the point, yeah? This seems a cleaner way to seperate resources based on the Folder Structure. Whatās your opinion about this?
Now, letās build and run our application. I will use postman to test this endpoint, as I will change certain Request Headers too.
First, send a GET request to localhost:xxx/api/language.
You can see that our implementation works right out of the box. As we mentioned earlier, if the request doesnt have information about the requested culture, the response would revert back to our default culture, that is, English. Now, letās try to request with the fr culture. There are 3 ways to do this.
- Specify the Culture in the Request Query String.
- Specify the Culture in Request Header,
- and store the preference culture in a cookie.
In this section, we will cover the first 2 ways to request for a particular culture.
Query String Based Culture Request
As you might have already guessed, in this approach we will just need to append a specific query to our request. Switch back to Postman and send a GET request to localhost:xxxx/api/Language**?culture=fr**
Easy, yeah? Like we talked about earlier letās change the culture to āarā an check the response.
As expected, we get a response with our default selected Culture, English.
Request Header Based Culture Request
Now, letās add the culture info to the header of the request. Itās quite simple to do in POSTMAN. Click on the Headers and add the key āAccept-Languageā and change the value to āfrā. You can receive the expected response.
Now that we learnt how to localize API response, letās implement the same in the Views too. Although the concept is same, there are slight variations that we will go through.
Localizing the Views
In this section, I will localize the HomePage View (Views/Home/Index.cshtml). To keep things simple, letās just implement this feature to transalte the Welcome and caption texts of this view.
Navigate to Views/Home/Index.cshtml and modify the following.
Line 1 - Previously for the controller we use a String Localizer. But here in the views, inorder to support HTMLs too, we use this IViewLocalizer Interface.
Line 7,8 - Like before, we use the localizer object and specify the key of the resource we need.
Finally, letās create the Resource. Remember the Folder convention that we used earlier? Make something similar here too.
Pretty self explanatory I guess. The only difference is that, here we use the HTML content too. Letās run the Application and see the Home Page.
The English Resources work. Letās add a query string here to change the culture to French.
Store the Culture Preference in a Cookie
Adding Query Strings or changing the Reuqest Headers may look like a convinient way while tsesting the application. But in practical / production scenarios, they are a big NO-NO. What would be better is to have the preferred Culture stored somewhere in the client machine, preferrably the client Browser as a cookie, right?
So, here is how it will work. In our Shared Layout, we will introduce a drop down which contains a list of available cultures. Once the user changes the DropDown Value, it should trigger a controller action that would set the selected culture on to a cookie, which would then reflect back on to our UI.
Before that we need to change our Service Registrations since we need a IOptions list of RequestCultures. Navigate to the Configure Services in the Startup class and add the following.
Then, in the Configure method, comment out all that we had added earlier and add this new line of code.
Next, letās create a partial view to hold the combobox (select) component. I had refered Microsoftās documentations for this. Under the Views/Shared Folderm add a new View and name it _CulturePartial.cshtml
Line 6,7 - Here, we are introducing the IOptions of the Request Localizer.
Line 16 - We are adding a form that would trigger the SetCulture Method of the CultureController (we will add this Controller in some time)
Now that we have created the partial view, letās add it to the Navigation bar. Open up the Views/Shared/_LoginPartial.cshtml and add this highlighted code.
We have not added the Controller yet. But. letās just run the application to check if we are able to render the select component within our layout.
With that working, letā add the Controller and Actions. We will also add resource for this Partial View so that āenā appears as English, āfrā as French asd so on. Get the point, yeah?
First, I will add the required Resources.
We have to make a slight change in the Partial View also.
Here, we use the Localizer Object to get the transalated string from the corresponding resource file. Next, add a new Controller, CultureController.
Line 10 - Here we add a new POST Method that will be invoked by the change in the Combobox.
Line 12-15, we create a new cookie with the selected culture information. We also set an expiration of 1 year to the cookie.
Letās Run the Application.
You can see that our implementation works well. Quite easy to implement Globalization and Localization in ASP.NET Core, right? We will finish this article here.
Summary - Globalization and Localization in ASP.NET Core
We learnt all about Globalization and Localization of ASP.NET Core Application following several recommended approaches. We covered topics like IStringLocalizer, View Localizer, Query based Culture, Request based Culture, and storing the Culture into the Cookie, and creating a select component to help the user select the prefered Culture. You can find the completed source code here. I hope you learnt something new and detailed in this article. If you have any comments or suggestions, please leave them behind in the comments section below. Do not forget to share this article within your developer community. Thanks and Happy Coding! :D