You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
6.7 KiB

---
sidebar_position: 2
title: User language selection
---
## Install localization
Install the `Microsoft.Extensions.Localization` package.
## Configure location
Open the `Program.cs` file:
```csharp title="Program.cs"
...
builder.Services.AddBlazoredModal();
// highlight-start
// Add the controller of the app
builder.Services.AddControllers();
// Add the localization to the app and specify the resources path
builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
// Configure the localtization
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
// Set the default culture of the web site
options.DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US"));
// Declare the supported culture
options.SupportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("fr-FR") };
options.SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("fr-FR") };
});
// highlight-end
var app = builder.Build();
...
app.UseRouting();
// highlight-start
// Get the current localization options
var options = ((IApplicationBuilder)app).ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
if (options?.Value != null)
{
// use the default localization
app.UseRequestLocalization(options.Value);
}
// Add the controller to the endpoint
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// highlight-end
app.MapBlazorHub();
...
```
In order to be able to change the culture, we will have to declare a controller.
Create a new folder at the root of the site named `Controllers`.
Create a new class called `CultureController`.
```csharp title="Controllers/CultureController.cs"
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
/// <summary>
/// The culture controller.
/// </summary>
[Route("[controller]/[action]")]
public class CultureController : Controller
{
/// <summary>
/// Sets the culture.
/// </summary>
/// <param name="culture">The culture.</param>
/// <param name="redirectUri">The redirect URI.</param>
/// <returns>
/// The action result.
/// </returns>
public IActionResult SetCulture(string culture, string redirectUri)
{
if (culture != null)
{
// Define a cookie with the selected culture
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture)));
}
return this.LocalRedirect(redirectUri);
}
}
```
## Language selector component
The following `CultureSelector` component shows how to set the user's culture selection.
The component is placed in the `Shared` folder for use throughout the application.
Create the `Shared/CultureSelector.razor` component.
```cshtml title="Shared/CultureSelector.razor"
@using System.Globalization
@inject NavigationManager NavigationManager
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr-FR")
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentUICulture == value)
{
return;
}
var culture = value.Name.ToLower(CultureInfo.InvariantCulture);
var uri = new Uri(this.NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var query = $"?culture={Uri.EscapeDataString(culture)}&" + $"redirectUri={Uri.EscapeDataString(uri)}";
// Redirect the user to the culture controller to set the cookie
this.NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
}
}
}
```
Add in the `<div class="top-row px-4">` div in `Shared/MainLayout.razor`, add the `CultureSelector` component:
```cshtml title="Shared/MainLayout.razor"
...
<main>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
// highlight-start
<div class="px-4">
<CultureSelector />
</div>
// highlight-end
</div>
...
```
Add the following code in the `Pages/Index.razor` file to visualize the language change.
```cshtml title="Pages/Index.razor"
@using System.Globalization
...
<p>
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>
...
```
## Concept: Controllers
Some actions are not possible with the razor model, such as the declaration of cookies on the fly, to declare a cookie it is absolutely necessary that no HTML element be displayed before.
In order to overcome this problem, we therefore use an MVC type controller without the View and Model part.
Here is a small definition of the MVC architecture:
The Model-View-Controller (MVC) architectural pattern separates an app into three main components: **M**odel, **V**iew, and **C**ontroller.
The MVC pattern helps you create apps that are more testable and easier to update than traditional monolithic apps.
MVC-based apps contain:
* **M**odels: Classes that represent the data of the app. The model classes use validation logic to enforce business rules for that data. Typically, model objects retrieve and store model state in a database.
* **V**iews: Views are the components that display the app's user interface (UI). Generally, this UI displays the model data.
* **C**ontrollers: Classes that:
* Handle browser requests.
* Retrieve model data.
* Call view templates that return a response.
In an MVC app, the view only displays information.
The controller handles and responds to user input and interaction.
For example, the controller handles URL segments and query-string values, and passes these values to the model. The model might use these values to query the database.
For example:
* `https://localhost:5001/Home/Privacy`: specifies the `Home` controller and the `Privacy` action.
* `https://localhost:5001/Movies/Edit/5`: is a request to edit the movie with `ID=5` using the `Movies` controller and the `Edit` action.
The MVC architectural pattern separates an app into three main groups of components: Models, Views, and Controllers.
This pattern helps to achieve separation of concerns: The UI logic belongs in the view. Input logic belongs in the controller.
Business logic belongs in the model.
This separation helps manage complexity when building an app, because it enables work on one aspect of the implementation at a time without impacting the code of another.
For example, you can work on the view code without depending on the business logic code.