Introduction
Hello Folks,
Today we will add the Multilingual feature to our .NET Core MVC 3.1 project with a few simple steps.
A multilingual website allows the site to reach a wider audience. ASP.NET Core provides services and middleware for localizing into different languages and cultures.
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.
Step 1
So let's start by registering and configuring the localization in the startup class.
- public void ConfigureServices(IServiceCollection services)
- {
-
- services.AddControllersWithViews();
- services.AddHttpContextAccessor();
-
- #region snippet1
- services.AddLocalization(options => options.ResourcesPath = "Resources");
- services.AddMvc()
- .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
- .AddDataAnnotationsLocalization();
-
- services.Configure<RequestLocalizationOptions>(options =>
- {
- var supportedCultures = new[] { "en-US", "hi-IN" };
- options.SetDefaultCulture(supportedCultures[0])
- .AddSupportedCultures(supportedCultures)
- .AddSupportedUICultures(supportedCultures) ;
- });
- #endregion
- }
Add the below code in the Configure method in the startup class.
- var supportedCultures = new[] { "en-US", "hi-IN" };
- var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
- .AddSupportedCultures(supportedCultures)
- .AddSupportedUICultures(supportedCultures);
-
- app.UseRequestLocalization(localizationOptions);
Step 2
For file specific resources:
Add a Resources folder to your project and add files as per your project hierarchy. Also, you can create a language-specific resource file, like the file given below.
- For Hindi - Index.hi-IN.resx
- For English - Index.hi-IN.resx
- For Common, If not available in above: Index.resx .
This will also have an Index.designer.cs class, which is the main class to fetch the resource value.
You can create one by adding an access modifier in Index.resx only. There is no need to select this option in all remaining language-specific files for Index View.
For View exists in Views/Home/Index.cshtml.
Resources/Views/Home/Index.resx
or
Resources/Views.Home.Index.resx
The same hierarchy will be followed for the controller and component model and so on.
For Shared resource
You need to create an empty class at the root of the project, as shown below:
-
-
- namespace TestDemo
- {
- public class CommonResources
- {
- }
- }
Also, the CommonResources resource file should be under the Resource folder.
We have now discussed the way to adding resource files. Now let's access the resources in our index.cshtml.
Index.cshtml
- @{
- ViewData["Title"] = "Home Page";
- }
- @using Microsoft.AspNetCore.Mvc.Localization
- @inject IViewLocalizer Localizer
- @inject IHtmlLocalizer<CommonResources> SharedLocalizer
-
- @Localizer["Testing"].Value
- <br/>
- @SharedLocalizer["Test"]
- <br/>
- @TestDemo.Resources.Resource.ResourceManager.GetString("Testing", System.Globalization.CultureInfo.CurrentCulture)
- <br />
- <div class="text-center">
- <h1 class="display-4">Welcome</h1>
- <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
- </div>
In the above image, we can see IViewLocalizer used for accessing view specific resource. Also, we can access the shared resource by IHtmlLocalizer<CommonResources> which we have created.
The alternate way to get the resource:
- @TestDemo.Resources.Resource.ResourceManager.GetString("Testing", System.Globalization.CultureInfo.CurrentCulture)
Let add a partial view for language selection and add its reference to _Layout.cshtml
Now create _SelectLanguagePartial.cshtml under Views/Shared/_SelectLanguagePartial.cshtml
- @using Microsoft.AspNetCore.Builder
- @using Microsoft.AspNetCore.Localization
- @using Microsoft.AspNetCore.Mvc.Localization
- @using Microsoft.Extensions.Options
-
- @inject IViewLocalizer Localizer
- @inject IOptions<RequestLocalizationOptions> LocOptions
-
- @{ var requestCulture = Context.Features.Get<IRequestCultureFeature>();
- var cultureItems = LocOptions.Value.SupportedUICultures
- .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
- .ToList();
- var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; }
-
- <div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
- <form id="selectLanguage" asp-controller="Home"
- asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
- method="post" class="form-horizontal" role="form">
- <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
- onchange="this.form.submit();"
- asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
- </select>
- </form>
- </div>
Add the below code to your _Layout.cshtml
- @using Microsoft.AspNetCore.Mvc.Localization
- @inject IViewLocalizer Localizer
- <li class="nav-item">
- @Localizer["Testing"].Value
- </li>
- <li class="nav-item float-right">
- @await Html.PartialAsync("_SelectLanguagePartial")
- </li>
Step 4
Now please add SetLanguage method to your controller called by language change view
- [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);
- }
That's it, now build and run your project. The output will be like:
Summary
In this article, we have added a multilingual feature to our project with simple steps.
I hope it helps!