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.

6.7 KiB

sidebar_position title
2 User language selection

Install localization

Install the Microsoft.Extensions.Localization package.

Configure location

Open the Program.cs file:

...

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.

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.

@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:

...
<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.

@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: Model, View, and Controller. The MVC pattern helps you create apps that are more testable and easier to update than traditional monolithic apps.

MVC-based apps contain:

  • Models: 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.
  • Views: Views are the components that display the app's user interface (UI). Generally, this UI displays the model data.
  • Controllers: 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.