In actual work, we often use ASP.NET Core’s Globalization & Localization features and resource files. Resource files (.resx) are used to separate language strings from code. These files contain key/values items. , you can use vs to create this file, for example: Your website supports 3 cultures – French, Spanish, English, so you have to create 2 types of resource files, such as French and Spanish
In this section I will show how to implement localization and globalization from different regions of the website
1 Controller uses IStringLocalizer object
2 Data Annotations error messages
3 Customer-defined validation error messages
4 Views use IViewLocalizer
We implement multilingual job application forms based on English, French and Spanish
1 Configure startup items
The first step is to tell the application the languages and cultures that the website will support, and add the Localization service and other settings to the application. Enter the Program class and add the following namespace:
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.Options; using System.Globalization;
Next add the following code:
builder.Services.AddControllersWithViews() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization(); builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fr"), new CultureInfo("es") }; options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; });
This code does 2 things:
1. Add localization features to Data Annotations and Views
2. Your website supports 3 cultures – French, Spanish, and English are defined as default
Allow the use of Localization services in the application
var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>(); app.UseRequestLocalization(locOptions.Value);
Use resource files to create globalization & localization features in ASP.NET Core
2 Use resource file DataAnnotations for localization
First create a Model to present the application job application form, then create a new class in the Models folder and name it JobApplication.cs. This class contains the following properties: Name, Email Address, DOB, etc. Apply the characteristics to these On fields, like [Required], [RegularExpression], [Range], [Display]
code show as below:
using AspNetCore.GlobalLocalResFiles.Infrastructure; using System.ComponentModel.DataAnnotations; using System.Xml.Linq; namespace AspNetCore.GlobalLocalResFiles.Models { public class JobApplication { [Required(ErrorMessage = "Please provide your name")] [Display(Name = "Job applicant name")] public string Name { get; set; } [RegularExpression("^[a-zA-Z0-9_\.-] + @([a-zA-Z0-9-] + \.) + [a-zA-Z]{2,6}$ ", ErrorMessage = "E-mail is not valid")] [Display(Name = "Job applicant email")] public string Email { get; set; } [CustomDate] [Display(Name = "Date of Birth")] public DateTime DOB { get; set; } [Required(ErrorMessage = "Please select your sex")] [Display(Name = "Job applicant sex")] public string Sex { get; set; } [Range(2, 4, ErrorMessage = "{0} must be a number between {1} and {2}")] [Display(Name = "Job applicant experience")] public int Experience { get; set; } [Range(typeof(bool), "true", "true", ErrorMessage = "You must accept the Terms")] [Display(Name = "Terms")] public bool TermsAccepted { get; set; } } }
Next, create resource files to store error messages and display names, so create two resource files in the Models folder and in the same directory as the JobApplication class: JobApplication.es.resx, JobApplication.fr.resx
NOTE: For the names of the resource files I used .es for spanish and .fr for french
In these resource files you can add strings (for example: error messages and display names) and their respective French and Spanish strings
As shown in the figure below, two resource files are displayed:
3 Customer-defined verification localization characters
We created a customer custom attribute called [CustomDate] for date of birth, specifying customer validation on the DOB field
[CustomDate] [Display(Name = "Date of Birth")] public DateTime DOB { get; set; }
Create a new class called CustomDate.cs in the Infrastructure folder. This class is responsible for validation, so you must inherit from the ValidationAttribute class. The code is as follows:
public class CustomDate : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var _localizationService = (IStringLocalizer<CustomDate>)validationContext.GetService(typeof(IStringLocalizer<CustomDate>)); if ((DateTime)value > DateTime.Now) return new ValidationResult(_localizationService["Date of Birth cannot be in the future"]); else if ((DateTime)value < new DateTime(1980, 1, 1)) return new ValidationResult(_localizationService["Date of Birth should not be before 1980"]); return ValidationResult.Success; } }
The IStringLocalizer object is used to obtain the resource class at runtime. It is a service used to provide localized strings stored in resource files.
var _localizationService = (IStringLocalizer<CustomDate>)validationContext.GetService(typeof(IStringLocalizer<CustomDate>));
Note that I use the following code to get the language-specified string from the resource file
_localizationService["Date of Birth cannot be in the future"] _localizationService["Date of Birth should not be before 1980"]
Next, create 2 resource files in the directory of the Custom verification class and name them:
CustomDate.es.resx
CustomDate.fr.resx
Add French and Spanish text strings to the resource file – Date of Birth cannot be in the future & Date of Birth should not be before 1980
4 The controller uses resource files for localization
When the form is submitted, the controller calls the action method. After the submission is successful, the information is displayed in these three languages based on the language and culture selected by the user.
Therefore, first we use the asp.net core dependency injection feature to inject the IStringLocalizer object in the constructor of the controller, and then traverse the language and culture associated with the string from the resource file. This message will be displayed to the form submitted by the user.
code show as below:
public class HomeController : Controller { private readonly IStringLocalizer<HomeController> _localizer; public HomeController(IStringLocalizer<HomeController> localizer) { _localizer = localizer; } public IActionResult Index() { return View(); } [HttpPost] public IActionResult Index(JobApplication jobApplication) { if (ModelState.IsValid) ViewBag.Message = _localizer["Your application is accepted"]; return View(); } }
_localizer is a variable containing an IStringLocalizer object which basically gives me the culture specific string stored in the resource file
Next, create 2 resource files in the Controllers folder, named: HomeController.es.resx, HomeController.fr.resx
Since I only have a single string “Your application is accepted”, both resource files have only one entry
The following two pictures are my controller resource files:
5 Views use resource files for localization
The IViewLocalizer service provides localization for view files, which can be injected into your view, as shown below:
@inject IViewLocalizer Localizer
The Job application form is in the Index view. First you add the necessary namespace to your view:
@using Microsoft.AspNetCore.Builder @using Microsoft.AspNetCore.Localization @using Microsoft.Extensions.Options @using Microsoft.AspNetCore.Mvc.Localization
Then inject IViewLocalizer & IOptions into the view, the code is as follows:
@inject IViewLocalizer Localizer @inject IOptions<RequestLocalizationOptions> LocOptions
Through the RequestLocalizationOptions object, I will populate the selection control with the language culture supported by the website, the user can select their culture and the form will be presented to the user based on the selected culture
Next add the following code to create and populate the selection control items
@{ var requestCulture = Context.Features.Get<IRequestCultureFeature>(); var cultureItems = LocOptions.Value.SupportedUICultures .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) .ToList(); } <label>Language:</label> <select onchange="SetCulture(this.value)" asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"> </select>
This short piece of JavaScript code will jump to the job application form where the user selects the culture.
<script> function SetCulture(selectedValue) { var url = window.location.href.split('?')[0]; var culture = "?culture=" + selectedValue + " & amp;ui-culture=" + selectedValue; window.location.href = url + culture; } </script>
Here a QueryStringRequestCultureProvider is used, where the user selected culture is added to the query string of the url, so the French version of the application form will be given a url like this:
https://localhost:44356/?culture=fr & amp;ui-culture=fr
The Spanish version of the form URL is as follows:
https://localhost:44356/?culture=es & amp;ui-culture=es
For the English version, we don’t need to add language and culture to the url.
https://localhost:44356
Next we will add the form to the view:
<form class="m-1 p-1" asp-action="Index" asp-route-culture="@culture" asp-route-ui-culture="@uiculture" method="post"> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="DOB"></label> <input asp-for="DOB" type="text" asp-format="{0:d}" class="form-control" /> <span asp-validation-for="DOB" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Sex"></label> <div> <input asp-for="Sex" type="radio" value="M" />@Localizer["Male"] <input asp-for="Sex" type="radio" value="F" />@Localizer["Female"] </div> <span asp-validation-for="Sex" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Experience"></label> <select asp-for="Experience" class="form-control"> <option value="Select">@Localizer["Select"]</option> <option value="0">Fresher</option> <option value="1">0-1 years</option> <option value="2">1-2 years</option> <option value="3">2-3 years</option> <option value="4">3-4 years</option> <option value="5">4-5 years</option> </select> <span asp-validation-for="Experience" class="text-danger"></span> </div> <div class="form-group"> <input asp-for="TermsAccepted" /> <label asp-for="TermsAccepted" class="form-check-label"> @Localizer["I accept the terms & conditions"] </label> <span asp-validation-for="TermsAccepted" class="text-danger"></span> </div> <button name="formsubmit" value="Button Control" type="submit" class="btn btn-primary">@Localizer["Submit Application"]</button> </form>
In the view we use IViewLocalizer to get the culture-related string, using the code -@Localizer[“SomeString”]
The following is the radio control code:
<input asp-for="Sex" type="radio" value="M" />@Localizer["Male"] <input asp-for="Sex" type="radio" value="F" />@Localizer["Female"]
Likewise, the terms tag does the same thing:
<label asp-for="TermsAccepted" class="form-check-label"> @Localizer["I accept the terms & conditions"] </label>
Next, create 2 resource files in the same directory as the view. As follows:
Index.es.resx
Index.fr.resx
Add necessary strings in the file as shown below
6 Test
Next let’s do a test, the first one will display the culture selected by the user, and the associated culture form will be displayed in the browser:
Next, the data annotation information will be displayed in Spanish & French versions
7 Resource file location
You can use the following code in the startup item to change the location of the resource file
services.AddLocalization(options => options.ResourcesPath = "Resources");
In this case, the HomeController’s resource files should be in either of 2 locations:
1. In the Resources/Controllers/ directory:
Resources/Controllers/HomeController.es.resx
Resources/Controllers/HomeController.fr.resx
2. In the Resources directory:
Resources/Controllers.HomeController.es.resx
Resources/Controllers.HomeController.fr.resx
Data Annotations resource files are located in either of the following 2 locations:
Resources/Models.JobApplication.es.resx
Resources/Models.JobApplication.fr.resx
or
Resources/Models/JobApplication.es.resx
Resources/Models/JobApplication.fr.resx
View resource files are located in either of the following 2 locations:
Resources/Views.Home.Index.es.resx
Resources/Views.Home.Index.fr.resx
or
Resources/Views/Home/Index.es.resx
Resources/Views/Home/Index.fr.resx
Source code address:
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.GlobalizationLocalization/AspNetCore.GlobalLocalResFiles
references
https://www.yogihosting.com/globalization-localization-resource-files-aspnet-core/