Partage via


Globalisation et localisation dans ASP.NET Core Blazor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Cet article explique comment restituer du contenu globalisé et localisé aux utilisateurs aux cultures et langues différentes.

Globalisation et localisation

Pour la globalisation, Blazor fournit la mise en forme des nombres et des dates. Pour la localisation, Blazor restitue le contenu à l’aide du système de ressources .NET.

Un ensemble limité de fonctionnalités de localisation d’ASP.NET Core sont prises en charge :

Pris en charge :IStringLocalizer et IStringLocalizer<T> sont pris en charge dans les applications Blazor.

Non pris en charge :IHtmlLocalizer, IViewLocalizer et la localisation des annotations de données sont des fonctionnalités MVC ASP.NET Core ; elles ne sont pas prises en charge dans les applications Blazor.

Cet article explique comment utiliser les fonctionnalités de globalisation et de localisation de Blazor en fonction des éléments suivants :

  • L’en-tête Accept-Language, qui est défini par le navigateur en fonction des préférences linguistiques d’un utilisateur dans les paramètres du navigateur.
  • La culture définie par l’application, qui n’est pas basée sur la valeur de l’en-tête Accept-Language. Le paramètre peut être statique pour tous les utilisateurs, ou dynamique en fonction de la logique de l’application. Lorsque le paramètre est basé sur la préférence de l’utilisateur, le paramètre est généralement enregistré pour être rechargé lors de visites ultérieures.

Pour des informations générales supplémentaires, consultez les ressources suivantes :

Souvent, les termes langue et culture sont utilisés indifféremment lorsqu’il s’agit de concepts de globalisation et de localisation.

Dans cet article, langue fait référence aux sélections effectuées par un utilisateur dans les paramètres de son navigateur. Les sélections de langue de l’utilisateur sont envoyées dans les requêtes de navigateur dans l’en-tête Accept-Language. Les paramètres du navigateur utilisent généralement le mot « langue » dans l’interface utilisateur.

La culture concerne les membres de .NET et de l’API Blazor. Par exemple, la requête d’un utilisateur peut inclure l’en-tête Accept-Language spécifiant une langue du point de vue de l’utilisateur, mais l’application définit la propriété CurrentCulture (« culture ») à partir de la langue demandée par l’utilisateur. L’API utilise généralement le mot « culture » dans ses noms de membres.

Les instructions de cet article ne couvrent pas la définition de l’attribut de langage HTML de la page (<html lang="...">), que les outils accessiblity utilisent. Vous pouvez définir la valeur statiquement en affectant un langage à l’attribut lang de la balise <html> ou vers document.documentElement.lang dans JavaScript. Vous pouvez définir dynamiquement la valeur de document.documentElement.lang avec de l’JSinteropérabilité.

Remarque

Les exemples de code de cet article utilisent les types de référence null (NRT, nullable reference types) et l'analyse statique de l'état null du compilateur .NET, qui sont pris en charge dans ASP.NET Core 6 et ses versions ultérieures. Lorsque vous ciblez ASP.NET Core 5.0 ou version antérieure, supprimez la désignation de type null (?) des exemples de l’article.

Globalisation

La directive d’attribut @bind applique des formats et analyse les valeurs d’affichage en fonction de la première langue préférée de l’utilisateur prise en charge par l’application. @bind prend en charge le paramètre @bind:culture pour fournir un System.Globalization.CultureInfo pour l’analyse et la mise en forme d’une valeur.

La culture actuelle est accessible à partir de la propriété System.Globalization.CultureInfo.CurrentCulture.

CultureInfo.InvariantCulture est utilisé pour les types de champs suivants (<input type="{TYPE}" />, où l’espace réservé {TYPE} est le type) :

  • date
  • number

Les types de champs précédents :

  • Sont affichés à l’aide de leurs règles de mise en forme basées sur le navigateur appropriées.
  • Ne peuvent pas contenir de texte de forme libre.
  • Fournissent des caractéristiques d’interaction utilisateur en fonction de l’implémentation du navigateur.

Blazor fournit une prise en charge intégrée du rendu des valeurs dans la culture actuelle. Par conséquent, la spécification d’une culture avec @bind:culture n’est pas recommandée lorsque les types de champs date et number sont utilisés.

Les types de champs suivants possèdent des exigences de mise en forme spécifiques et ne sont actuellement pas pris en charge par l’ensemble des navigateurs principaux. Ils ne sont ainsi pas pris en charge par Blazor :

  • datetime-local
  • month
  • week

Pour connaître la prise en charge actuelle des navigateurs des types précédents, consultez Puis-je utiliser.

Globalisation .NET et prise en charge (Blazor WebAssembly) des composants internationaux pour Unicode (ICU)

Blazor WebAssembly utilise une API de globalisation réduite et un ensemble de paramètres régionaux pour les composants internationaux Unicode (ICU) intégrés. Pour plus d’informations, consultez Globalisation .NET et ICU : ICU sur WebAssembly.

Pour charger un fichier de données DCU personnalisé et contrôler les paramètres régionaux de l’application, consultez l’ICU de globalisation WASM. Actuellement, la génération manuelle du fichier de données d’ICU personnalisé est requise. Les outils .NET pour faciliter le processus de création du fichier sont prévus pour .NET 9 en novembre 2024.

Blazor WebAssembly utilise une API de globalisation réduite et un ensemble de paramètres régionaux pour les composants internationaux Unicode (ICU) intégrés. Pour plus d’informations, consultez Globalisation .NET et ICU : ICU sur WebAssembly.

Le chargement d’un sous-ensemble personnalisé de paramètres régionaux dans une application Blazor WebAssembly est pris en charge dans .NET 8 ou version ultérieure. Pour plus d'informations, accédez à cette section pour la version 8.0 ou ultérieure de cet article.

Globalisation invariante

Cette section s’applique uniquement aux scénarios Blazor côté client.

Si l’application ne nécessite pas de localisation, configurez l’application pour prendre en charge la culture invariante, qui est généralement basée sur l’anglais des États-Unis (en-US). L’utilisation de la globalisation invariante réduit la taille de téléchargement de l’application et permet un démarrage plus rapide de l’application. Définissez la propriété InvariantGlobalization sur true dans le fichier projet de l’application (.csproj) :

<PropertyGroup>
  <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>

Vous pouvez également configurer la globalisation invariante avec les approches suivantes :

  • Dans runtimeconfig.json:

    {
      "runtimeOptions": {
        "configProperties": {
          "System.Globalization.Invariant": true
        }
      }
    }
    
  • Avec une variable d’environnement :

    • Clé :DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
    • Valeur : true ou 1

Pour plus d’informations, consultez Options de configuration d’exécution pour la globalisation (documentation .NET).

Informations de fuseau horaire

Cette section s’applique uniquement aux scénarios Blazor côté client.

L’adoption d’une globalisation invariante entraîne uniquement l’utilisation de noms de fuseaux horaires non localisés. Pour découper le code et les données de fuseau horaire, ce qui réduit la taille de téléchargement de l’application et permet un démarrage plus rapide de l’application, appliquez la propriété MSBuild <InvariantTimezone> avec la valeur true dans le fichier projet de l’application :

<PropertyGroup>
  <InvariantTimezone>true</InvariantTimezone>
</PropertyGroup>

Remarque

<BlazorEnableTimeZoneSupport> remplace un paramètre <InvariantTimezone> antérieur. Nous vous recommandons de supprimer le paramètre <BlazorEnableTimeZoneSupport>.

Un fichier de données est inclus pour que les informations de fuseau horaire soient correctes. Si l’application n’a pas besoin de cette fonctionnalité, vous pouvez la désactiver en définissant la propriété MSBuild <BlazorEnableTimeZoneSupport> sur la valeur false dans le fichier projet de l’application :

<PropertyGroup>
  <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
</PropertyGroup>

Composant de démonstration

Le composant CultureExample1 suivant peut être utilisé pour illustrer les concepts de globalisation et de localisation de Blazor abordés par cet article.

CultureExample1.razor:

@page "/culture-example-1"
@using System.Globalization

<h1>Culture Example 1</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

Le format de chaîne numérique (N2) dans l’exemple précédent (.ToString("N2")) est un spécificateur de format numérique .NET standard. Le format N2 est pris en charge pour tous les types numériques, inclut un séparateur de groupe et affiche jusqu’à deux décimales.

Si vous le souhaitez, ajoutez un élément de menu à la navigation dans le composant NavMenu (NavMenu.razor) pour le composant CultureExample1.

Définir dynamiquement la culture à partir de l’en-tête Accept-Language

Ajoutez le package Microsoft.Extensions.Localization à l’application.

L’en-tête Accept-Language est défini par le navigateur et contrôlé par les préférences linguistiques de l’utilisateur dans les paramètres du navigateur. Dans les paramètres du navigateur, un utilisateur définit une ou plusieurs langues préférées par ordre de préférence. L’ordre de préférence est utilisé par le navigateur pour définir des valeurs de qualité (q, 0-1) pour chaque langue dans l’en-tête. L’exemple suivant spécifie l’anglais des États-Unis, l’anglais et l’espagnol du Costa Rica avec une préférence pour l’anglais des États-Unis ou l’anglais :

Accept-Language : en-US,en;q=0.9,es-CL;q=0.8

La culture de l’application est définie en mettant en correspondance la première langue demandée qui correspond à une culture prise en charge de l’application.

Lors du développement côté client, définissez la propriété BlazorWebAssemblyLoadAllGlobalizationData sur true dans le fichier projet de l’application côté client (.csproj) :

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Lors du développement côté client, la définition dynamique de la culture à partir de l’en-tête Accept-Language n’est pas prise en charge.

Remarque

Si la spécification de l’application nécessite de limiter les cultures prises en charge à une liste explicite, consultez la section Définir dynamiquement la culture côté client par préférence utilisateur de cet article.

Les applications sont localisées à l’aide d’un intergiciel de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Ajoutez la ligne suivante au fichier Program dans lequel les services sont inscrits :

builder.Services.AddLocalization();

Dans le développement côté serveur, spécifiez les cultures prises en charge par l’application avant tout intergiciel qui peut vérifier la culture de la requête. En règle générale, placez le middleware de localisation de la requête immédiatement avant d’appeler MapRazorComponents. L’exemple suivant configure les cultures prises en charge pour l’anglais des États-Unis et l’espagnol du Costa Rica :

Dans le développement côté serveur, spécifiez les cultures prises en charge par l’application immédiatement après l’ajout du middleware de routage (UseRouting) au pipeline de traitement. L’exemple suivant configure les cultures prises en charge pour l’anglais des États-Unis et l’espagnol du Costa Rica :

app.UseRequestLocalization(new RequestLocalizationOptions()
    .AddSupportedCultures(new[] { "en-US", "es-CR" })
    .AddSupportedUICultures(new[] { "en-US", "es-CR" }));

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciels du fichier Program, consultez Intergiciel ASP.NET Core.

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une requête avec l’anglais des États-Unis (en-US). Passez à l’espagnol du Costa Rica (es-CR) dans les paramètres linguistiques du navigateur. Demandez à nouveau la page web.

Remarque

Certains navigateurs vous obligent à utiliser le paramètre de langue par défaut pour les requêtes et les propres paramètres d’interface utilisateur du navigateur. Cela peut rendre difficile la modification de la langue sur une langue que vous comprenez, car tous les écrans de l’interface utilisateur de paramètres peuvent se retrouver dans une langue que vous ne pouvez pas lire. Un navigateur comme Opera est un bon choix pour les tests, car il vous permet de définir une langue par défaut pour les requêtes de page web, tout en laissant l’interface utilisateur des paramètres du navigateur dans votre langue.

Lorsque la culture est l’anglais des États-Unis (en-US), le composant rendu utilise la mise en forme de date mois/jour (6/7), une heure sur le modèle de 12 heures (AM/PM) et des virgules de séparation dans les nombres avec un point pour la valeur décimale (1,999.69) :

  • Date : 6/7/2021 6:45:22 AM
  • Number : 1,999.69

Lorsque la culture est l’espagnol du Costa Rica (es-CR), le composant rendu utilise la mise en forme de date jour/mois (7/6), une heure sur le modèle de 24 heures et des points comme séparateur de nombres avec une virgule pour la valeur décimale (1.999,69) :

  • Date : 7/6/2021 6:49:38
  • Number : 1.999,69

Définir statiquement la culture côté client

Définissez la propriété BlazorWebAssemblyLoadAllGlobalizationData sur true dans le fichier projet de l’application (.csproj) :

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Par défaut, la configuration de l’éditeur de liaison pour Intermediate Language (IL) du rendu côté client supprime les informations d’internationalisation, à l’exception des paramètres régionaux explicitement demandés. Pour plus d’informations, consultez Configurer l’éditeur de liens pour ASP.NET Core Blazor.

La culture de l’application peut être définie en JavaScript lorsque Blazor commence par l’option de démarrage applicationCultureBlazor. L’exemple suivant configure le lancement de l’application à l’aide de la culture Anglais des États-Unis (en-US).

Empêcher Blazor le démarrage automatique en ajoutant autostart="false" à la Blazorbalise<script> de :

<script src="{BLAZOR SCRIPT}" autostart="false"></script>

Dans l’exemple précédent, l’espace réservé {BLAZOR SCRIPT} est le chemin d’accès de script Blazor et le nom de fichier. Pour connaître l’emplacement du script, consultez ASP.NET Core Blazor structure du projet.

Ajoutez le bloc <script> suivant après la balise Blazor de <script> et avant la balise </body> fermante :

Blazor Web App:

<script>
  Blazor.start({
    webAssembly: {
      applicationCulture: 'en-US'
    }
  });
</script>

Blazor WebAssembly autonome :

<script>
  Blazor.start({
    applicationCulture: 'en-US'
  });
</script>

La valeur pour applicationCulture doit être conforme au format de balise de langue BCP-47. Pour plus d’informations sur le démarrage de Blazor, consultez Démarrage d’ASP.NET Core Blazor.

Une alternative à la définition de l’option de démarrage Blazor de la culture consiste à définir la culture en code C#. Définissez CultureInfo.DefaultThreadCurrentCulture et CultureInfo.DefaultThreadCurrentUICulture dans le fichier Program sur la même culture.

Ajoutez l’espace de noms System.Globalization au fichier Program :

using System.Globalization;

Ajoutez les paramètres de culture avant la ligne qui génère et exécute WebAssemblyHostBuilder (await builder.Build().RunAsync();) :

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

Remarque

Actuellement, les applications Blazor WebAssembly chargent uniquement les ressources en fonction de DefaultThreadCurrentCulture. Pour plus d’informations, consultez Blazor WASM s’appuie uniquement sur la culture actuelle (la culture d’interface utilisateur actuelle n’est pas respectée) (dotnet/aspnetcore #56824).

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une requête avec l’anglais des États-Unis (en-US). Passez à l’espagnol du Costa Rica (es-CR) dans les paramètres linguistiques du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol du Costa Rica, la culture de l’application reste l’anglais des États-Unis (en-US).

Définir statiquement la culture côté serveur

Les applications côté serveur sont localisées à l’aide d’un intergiciel de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans le fichier Program :

builder.Services.AddLocalization();

Spécifiez la culture statique dans le Program fichier avant tout intergiciel qui peut vérifier la culture de la requête. En règle générale, placez l’intergiciel de localisation des requêtes juste avant MapRazorComponents. L’exemple suivant configure l’anglais des États-Unis :

Spécifiez la culture statique dans le Program fichier immédiatement après l’ajout du middleware de routage (UseRouting) au pipeline de traitement. L’exemple suivant configure l’anglais des États-Unis :

app.UseRequestLocalization("en-US");

La valeur de culture pour UseRequestLocalization doit être conforme au format de balise de langue BCP-47.

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciels du fichier Program, consultez Intergiciel ASP.NET Core.

Les applications côté serveur sont localisées à l’aide d’un intergiciel de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

Spécifiez la culture statique dans Startup.Configure (Startup.cs) immédiatement après l’ajout de l’intergiciel de routage au pipeline de traitement. L’exemple suivant configure l’anglais des États-Unis :

app.UseRequestLocalization("en-US");

La valeur de culture pour UseRequestLocalization doit être conforme au format de balise de langue BCP-47.

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciel de Startup.Configure, consultez Intergiciels ASP.NET Core.

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une requête avec l’anglais des États-Unis (en-US). Passez à l’espagnol du Costa Rica (es-CR) dans les paramètres linguistiques du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol du Costa Rica, la culture de l’application reste l’anglais des États-Unis (en-US).

Définir dynamiquement la culture côté client par préférence utilisateur

Des exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent le stockage local du navigateur (courant avec le scénario côté client), un cookie ou une base de données de localisation (courant avec le scénario côté serveur), ou un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser le stockage local du navigateur.

Ajoutez le package Microsoft.Extensions.Localization à l’application.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Définissez la propriété BlazorWebAssemblyLoadAllGlobalizationData sur true dans le fichier projet :

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

La culture de l'application pour le rendu côté client est définie à l'aide de l'API du framework Blazor. La sélection de culture d’un utilisateur peut être conservée dans le stockage local du navigateur.

Fournir des JS fonctions après Blazor la <script>balise pour obtenir et définir la sélection de la culture de l’utilisateur avec le stockage local du navigateur :

<script>
  window.blazorCulture = {
    get: () => window.localStorage['BlazorCulture'],
    set: (value) => window.localStorage['BlazorCulture'] = value
  };
</script>

Remarque

L’exemple précédent pollue le client avec des fonctions globales. Pour une meilleure approche dans les applications de production, consultez Isolation JavaScript dans les modules JavaScript.

Ajoutez les espaces de noms pour System.Globalization et Microsoft.JSInterop en haut du fichier Program :

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante :

- await builder.Build().RunAsync();

Remplacez la ligne précédente par le code suivant. Le code ajoute le service de localisation de Blazor à la collection de services de l’application avec AddLocalization, et utilise l’interopérabilité JS pour appeler JS et récupérer la sélection de la culture de l’utilisateur à partir du stockage local. Si le stockage local ne contient pas de culture pour l’utilisateur, le code définit la valeur par défaut Anglais des États-Unis (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);

if (result == null)
{
    await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Remarque

Actuellement, les applications Blazor WebAssembly chargent uniquement les ressources en fonction de DefaultThreadCurrentCulture. Pour plus d’informations, consultez Blazor WASM s’appuie uniquement sur la culture actuelle (la culture d’interface utilisateur actuelle n’est pas respectée) (dotnet/aspnetcore #56824).

Le composant CultureSelector suivant montre comment effectuer les actions suivantes :

  • Définissez la sélection de culture de l’utilisateur dans le stockage local du navigateur via l’interopérabilité JS.
  • Rechargez le composant demandé (forceLoad: true), qui utilise la culture mise à jour.

CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @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("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
        }
    }
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @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("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
    {
        selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);

        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
        }
    }
}

À l’intérieur de la balise fermante de l’élément </main> du composant MainLayout (MainLayout.razor), ajoutez le composant CultureSelector :

<article class="bottom-row px-4">
    <CultureSelector />
</article>

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de l’exemple précédent.

Définir dynamiquement la culture côté serveur par préférence utilisateur

Des exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent le stockage local du navigateur (courant avec les scénarios côté client), un cookie ou une base de données de localisation (courant avec les scénarios côté serveur), ou un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser un cookie de localisation.

Remarque

L’exemple suivant suppose que l’application adopte une interactivité globale en spécifiant le rendu interactif côté serveur (interactive SSR) sur le composant Routes dans le composant App (Components/App.razor) :

<Routes @rendermode="InteractiveServer" />

Si l’application adopte l’interactivité par page/composant , consultez les remarques à la fin de cette section pour modifier les modes de rendu des composants de l’exemple.

Ajoutez le package Microsoft.Extensions.Localization à l’application.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Les applications côté serveur sont localisées à l’aide d’un intergiciel de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans le fichier Program :

builder.Services.AddLocalization();

Définissez les cultures par défaut et prises en charge de l’application avec RequestLocalizationOptions.

Avant l’appel à MapRazorComponents dans le pipeline de traitement des requêtes, placez le code suivant :

Une fois le middleware de routage (UseRouting) ajouté au pipeline de traitement des demandes, placez le code suivant :

var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciels, consultez Intergiciel ASP.NET Core.

L’exemple suivant montre comment définir la culture actuelle dans un cookie qui peut être lu par l’intergiciel de localisation.

Les espaces de noms suivants sont requis pour le composant App :

Ajoutez ce qui suit en haut du fichier de composant App (Components/App.razor) :

@using System.Globalization
@using Microsoft.AspNetCore.Localization

Ajoutez le bloc @code suivant au bas du fichier de composant App :

@code {
    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    protected override void OnInitialized()
    {
        HttpContext?.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }
}

Les modifications apportées au fichier Pages/_Host.cshtml nécessitent les espaces de noms suivants :

Ajoutez le code suivant au fichier :

@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciels, consultez Intergiciel ASP.NET Core.

Si l’application n’est pas configurée pour traiter les actions du contrôleur :

  • Ajoutez des services MVC en appelant AddControllers sur la collection de services dans le fichier Program :

    builder.Services.AddControllers();
    
  • Ajoutez le routage du point de terminaison du contrôleur dans le fichier Program en appelant MapControllers sur le IEndpointRouteBuilder (app) :

    app.MapControllers();
    

Pour fournir une interface utilisateur permettant à un utilisateur de sélectionner une culture, utilisez une approche basée sur la redirection avec un cookie de localisation. L’application conserve la culture sélectionnée de l’utilisateur via une redirection vers un contrôleur. Le contrôleur définit la culture sélectionnée de l’utilisateur dans un cookie et redirige l’utilisateur vers l’URI d’origine. Le processus est similaire à ce qui se produit dans une application web lorsqu’un utilisateur tente d’accéder à une ressource sécurisée, où l’utilisateur est redirigé vers une page de connexion, puis vers la ressource d’origine.

Controllers/CultureController.cs:

using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture, culture)));
        }

        return LocalRedirect(redirectUri);
    }
}

Avertissement

Utilisez le résultat de l’action LocalRedirect, comme indiqué dans l’exemple précédent, pour empêcher les attaques de redirection ouvertes. Pour plus d’informations, consultez Empêcher les attaques par redirection ouverte dans ASP.NET Core.

Le composant CultureSelector suivant montre comment appeler la méthode Set de CultureController avec la nouvelle culture. Le composant est placé dans le dossier Shared pour une utilisation dans l’ensemble de l’application.

CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @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("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @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("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
    {
        selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);

        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}

Ajoutez le composant CultureSelector au composant MainLayout. Placez la balise suivante à l’intérieur de la balise de fermeture </main> dans le fichier Components/Layout/MainLayout.razor :

Ajoutez le composant CultureSelector au composant MainLayout. Placez la balise suivante à l’intérieur de la balise de fermeture </main> dans le fichier Shared/MainLayout.razor :

<article class="bottom-row px-4">
    <CultureSelector />
</article>

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de l’exemple précédent.

L’exemple précédent suppose que l’application adopte l’interactivité globale en spécifiant le mode de rendu de serveur interactif sur le composant Routes dans le composant App (Components/App.razor) :

<Routes @rendermode="InteractiveServer" />

Si l’application adopte l’interactivité par page/composant, apportez les modifications suivantes :

  • Ajoutez le mode de rendu Serveur interactif en haut du fichier du composant CultureExample1 (Components/Pages/CultureExample1.razor) :

    @rendermode InteractiveServer
    
  • Dans la présentation principale de l’application (Components/Layout/MainLayout.razor), appliquez le mode de rendu Serveur interactif au composant CultureSelector :

    <CultureSelector @rendermode="InteractiveServer" />
    

Définir dynamiquement la culture d’une Blazor Web App en fonction des préférences de l’utilisateur

Cette section s’applique aux Blazor Web Apps qui adoptent l’interactivité automatique (serveur et WebAssembly).

Les préférences de l’utilisateur peuvent être stockées, par exemple, dans le stockage local du navigateur (courant pour les scénarios côté client), dans un cookie ou une base de données de localisation (courant pour les scénarios côté serveur), à la fois dans le stockage local et dans un cookie de localisation (Blazor Web Apps avec serveur et composants WebAssembly), ou dans un service externe rattaché à une base de données externe et accessible par une API Web. L’exemple suivant montre comment utiliser le stockage local du navigateur pour les composants rendus côté client (CSR) et une localisation cookie pour les composants rendus côté serveur (SSR).

Mises à jour du projet .Client

Ajoutez le Microsoft.Extensions.Localization package au projet.Client.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Définissez la propriété BlazorWebAssemblyLoadAllGlobalizationData sur true dans le .Client fichier projet :

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Ajoutez les espaces de noms pour System.Globalization et Microsoft.JSInterop au début du fichier .Client du projetProgram :

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante :

- await builder.Build().RunAsync();

Remplacez la ligne précédente par le code suivant. Le code ajoute le service de localisation de Blazor à la collection de services de l’application avec AddLocalization, et utilise l’interopérabilité JS pour appeler JS et récupérer la sélection de la culture de l’utilisateur à partir du stockage local. Si le stockage local ne contient pas de culture pour l’utilisateur, le code définit la valeur par défaut Anglais des États-Unis (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);

if (result == null)
{
    await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Remarque

Actuellement, les applications Blazor WebAssembly chargent uniquement les ressources en fonction de DefaultThreadCurrentCulture. Pour plus d’informations, consultez Blazor WASM s’appuie uniquement sur la culture actuelle (la culture d’interface utilisateur actuelle n’est pas respectée) (dotnet/aspnetcore #56824).

Ajoutez le composant CultureSelector suivant au projet .Client.

Le composant adopte les approches suivantes pour travailler pour les composants SSR ou CSR :

  • Le nom d’affichage de chaque culture disponible dans la liste déroulante est fourni par un dictionnaire parce que les données de globalisation côté client incluent le texte localisé des noms d’affichage des cultures que les données de globalisation côté serveur fournissent. Par exemple, la localisation côté serveur affiche English (United States) lorsque en-US est la culture et Ingles () lorsqu’une autre culture est utilisée. Étant donné que la localisation des noms d’affichage de la culture n’est pas disponible avec Blazor WebAssembly globalisation, le nom d’affichage pour les États-Unis anglais sur le client pour toute culture chargée n’est que en-US. L’utilisation d’un dictionnaire personnalisé permet au composant d’afficher au moins des noms complets de culture anglaise.
  • Lorsque l’utilisateur(-trice) modifie la culture, JS l’interopérabilité définit la culture dans le stockage du navigateur local et une action de contrôleur met à jour la localisation cookie avec la culture. Le contrôleur est ajouté à l’application plus loin dans la section des mises à jour du projet Server.

Pages/CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="@selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@cultureDict[culture.Name]</option>
            }
        </select>
    </label>
</p>

@code
{
    private Dictionary<string, string> cultureDict = 
        new()
        {
            { "en-US", "English (United States)" },
            { "es-CR", "Spanish (Costa Rica)" }
        };

    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}

Dans le projet .Client, placez le composant CultureClient suivant pour étudier le fonctionnement de la mondialisation pour les composants CSR.

Pages/CultureClient.razor:

@page "/culture-client"
@rendermode InteractiveWebAssembly
@using System.Globalization

<PageTitle>Culture Client</PageTitle>

<h1>Culture Client</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

Mise à jour du projet serveur

Ajoutez le package Microsoft.Extensions.Localization au projet du serveur.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Les applications côté serveur sont localisées à l’aide d’un intergiciel de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans le fichier Program du projet de serveur où les services sont enregistrés :

builder.Services.AddLocalization();

Définissez les cultures par défaut et prises en charge de l’application avec RequestLocalizationOptions.

Avant l’appel à MapRazorComponents dans le pipeline de traitement des requêtes, placez le code suivant :

var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

L’exemple suivant montre comment définir la culture actuelle dans un cookie qui peut être lu par l’intergiciel de localisation.

Les espaces de noms suivants sont requis pour le composant App :

Ajoutez ce qui suit en haut du fichier de composant App (Components/App.razor) :

@using System.Globalization
@using Microsoft.AspNetCore.Localization

La culture de l'application pour le rendu côté client est définie à l'aide de l'API du framework Blazor. La sélection de la culture d’un utilisateur peut être conservée dans le stockage local du navigateur pour les composants CSR.

Après Blazorla <script>balise, fournir des fonctionsJS pour obtenir et définir la sélection de la culture de l’utilisateur avec le stockage local du navigateur :

<script>
  window.blazorCulture = {
    get: () => window.localStorage['BlazorCulture'],
    set: (value) => window.localStorage['BlazorCulture'] = value
  };
</script>

Remarque

L’exemple précédent pollue le client avec des fonctions globales. Pour une meilleure approche dans les applications de production, consultez Isolation JavaScript dans les modules JavaScript.

Ajoutez le bloc @code suivant au bas du fichier de composant App :

@code {
    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    protected override void OnInitialized()
    {
        HttpContext?.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }
}

Si le projet de serveur n’est pas configuré pour traiter les actions du contrôleur :

  • Ajoutez des services MVC en appelant AddControllers sur la collection de services dans le fichier Program :

    builder.Services.AddControllers();
    
  • Ajoutez le routage du point de terminaison du contrôleur dans le fichier Program en appelant MapControllers sur le IEndpointRouteBuilder (app) :

    app.MapControllers();
    

Pour permettre à l’utilisateur de sélectionner une culture pour les composants SSR, utilisez une approche basée sur la redirection avec une localisationcookie. L’application conserve la culture sélectionnée de l’utilisateur via une redirection vers un contrôleur. Le contrôleur définit la culture sélectionnée de l’utilisateur dans un cookie et redirige l’utilisateur vers l’URI d’origine. Le processus est similaire à ce qui se produit dans une application web lorsqu’un utilisateur tente d’accéder à une ressource sécurisée, où l’utilisateur est redirigé vers une page de connexion, puis vers la ressource d’origine.

Controllers/CultureController.cs:

using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture, culture)));
        }

        return LocalRedirect(redirectUri);
    }
}

Avertissement

Utilisez le résultat de l’action LocalRedirect, comme indiqué dans l’exemple précédent, pour empêcher les attaques de redirection ouvertes. Pour plus d’informations, consultez Empêcher les attaques par redirection ouverte dans ASP.NET Core.

Ajoutez le composant CultureSelector au composant MainLayout. Placez la balise suivante à l’intérieur de la balise de fermeture </main> dans le fichier Components/Layout/MainLayout.razor :

<article class="bottom-row px-4">
    <CultureSelector @rendermode="InteractiveAuto" />
</article>

Utilisez le composant CultureExample1 indiqué dans la section Composant de démonstration pour étudier le fonctionnement de l’exemple précédent.

Dans le projet de serveur, placez le composant CultureServer suivant pour étudier le fonctionnement de la globalisation pour les composants SSR.

Components/Pages/CultureServer.razor:

@page "/culture-server"
@rendermode InteractiveServer
@using System.Globalization

<PageTitle>Culture Server</PageTitle>

<h1>Culture Server</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

Ajoutez les composants CultureClient et CultureServer à la barre latérale dans Components/Layout/NavMenu.razor :

<div class="nav-item px-3">
    <NavLink class="nav-link" href="culture-server">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Server)
    </NavLink>
</div>
<div class="nav-item px-3">
    <NavLink class="nav-link" href="culture-client">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Client)
    </NavLink>
</div>

Composants automatiques interactifs

Les conseils de cette section fonctionnent également pour les composants qui adoptent le mode de rendu automatique interactif :

@rendermode InteractiveAuto

Localisation

Si l’application ne prend pas déjà en charge la sélection de culture dynamique, ajoutez le package Microsoft.Extensions.Localization à l’application.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Localisation côté client

Définissez la propriété BlazorWebAssemblyLoadAllGlobalizationData sur true dans le fichier projet de l’application (.csproj) :

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Dans le fichier Program, ajoutez l’espace de noms pour System.Globalization en haut du fichier :

using System.Globalization;

Ajoutez le service de localisation de Blazor à la collection de services de l’application avec AddLocalization :

builder.Services.AddLocalization();

Localisation côté serveur

Utilisez l’intergiciel de localisation pour définir la culture de l’application.

Si l’application ne prend pas déjà en charge la sélection de culture dynamique :

  • Ajoutez des services de localisation à l’application avec AddLocalization.
  • Spécifiez les cultures par défaut et prises en charge de l’application dans le fichier Program. L’exemple suivant configure les cultures prises en charge pour l’anglais des États-Unis et l’espagnol du Costa Rica.
builder.Services.AddLocalization();

Placez le middleware de localisation des requêtes avant tout intergiciel qui peut vérifier la culture de la requête. En règle générale, placez le middleware immédiatement avant d’appeler MapRazorComponents:

Immédiatement après l’ajout du middlewareUseRouting de routage au pipeline de traitement :

var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciels, consultez Intergiciel ASP.NET Core.

  • Ajoutez des services de localisation à l’application avec AddLocalization.
  • Spécifiez les cultures par défaut et prises en charge de l’application dans Startup.Configure (Startup.cs). L’exemple suivant configure les cultures prises en charge pour l’anglais des États-Unis et l’espagnol du Costa Rica.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

Dans Startup.Configure immédiatement après l’ajout du middleware de routage auUseRouting pipeline de traitement :

var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Pour plus d’informations sur la commande d’intergiciels de localisation dans le pipeline d’intergiciel de Startup.Configure, consultez Intergiciels ASP.NET Core.

Si l’application doit localiser des ressources en fonction du stockage du paramètre de culture d’un utilisateur, utilisez un cookie de culture de localisation. L’utilisation d’un cookie garantit que la connexion WebSocket peut propager correctement la culture. Si les schémas de localisation sont basés sur le chemin d’URL ou la chaîne de requête, le schéma peut ne pas être en mesure de fonctionner avec WebSockets pour conserver la culture. Par conséquent, l’approche recommandée consiste à utiliser un cookie de culture de localisation. Consultez la section Définir dynamiquement la culture côté serveur par préférence utilisateur de cet article pour voir un exemple d’expression Razor qui conserve la sélection de culture de l’utilisateur.

Exemple de ressources localisées

L’exemple de ressources localisées dans cette section fonctionne avec les exemples précédents de cet article, où les cultures prises en charge de l’application sont l’anglais (en) comme paramètre régional par défaut et l’espagnol (es) comme paramètre régional alternatif sélectionnable par l’utilisateur ou spécifié par le navigateur.

Créez un fichier de ressources pour chacun des paramètres régionaux. Dans l’exemple suivant, des ressources sont créées pour une chaîne Greeting en anglais et en espagnol :

  • Anglais (en) : Hello, World!
  • Espagnol (es) : ¡Hola, Mundo!

Remarque

Vous pouvez ajouter le fichier de ressources suivant dans Visual Studio en cliquant avec le bouton droit sur le dossier Pages et en sélectionnant Ajouter>Nouvel élément>Fichier de ressources. Nommez le fichier CultureExample2.resx. Lorsque l’éditeur s’affiche, fournissez des données pour une nouvelle entrée. Définissez le Nom sur Greeting et la Valeur sur Hello, World!. Enregistrez le fichier.

Si vous utilisez Visual Studio Code, nous vous recommandons d’installer l’outil ResX Viewer and Editor de Tim Heuer. Ajoutez un fichier CultureExample2.resx vide au dossier Pages. L’extension prend automatiquement en charge la gestion du fichier dans l’interface utilisateur. Sélectionnez le bouton Ajouter une nouvelle ressource. Suivez les instructions pour ajouter une entrée pour Greeting (clé), Hello, World! (valeur) et None (commentaire). Enregistrez le fichier. Si vous fermez et rouvrez le fichier, vous pouvez voir la ressource Greeting.

L’outil ResX Viewer and Editor de Tim Heuer n’est ni détenu ni géré par Microsoft et n’est couvert par aucun contrat de support ou licence Microsoft.

L’exemple suivant illustre un fichier de ressources standard. Vous pouvez placer manuellement les fichiers de ressources dans le dossier Pages de l’application si vous préférez ne pas utiliser d’outils intégrés avec un environnement de développement intégré (IDE), tel que l’éditeur de fichiers de ressources intégré de Visual Studio ou Visual Studio Code avec une extension pour créer et éditer des fichiers de ressources.

Pages/CultureExample2.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Greeting" xml:space="preserve">
    <value>Hello, World!</value>
  </data>
</root>

Remarque

Vous pouvez ajouter le fichier de ressources suivant dans Visual Studio en cliquant avec le bouton droit sur le dossier Pages et en sélectionnant Ajouter>Nouvel élément>Fichier de ressources. Nommez le fichier CultureExample2.es.resx. Lorsque l’éditeur s’affiche, fournissez des données pour une nouvelle entrée. Définissez le Nom sur Greeting et la Valeur sur ¡Hola, Mundo!. Enregistrez le fichier.

Si vous utilisez Visual Studio Code, nous vous recommandons d’installer l’outil ResX Viewer and Editor de Tim Heuer. Ajoutez un fichier CultureExample2.resx vide au dossier Pages. L’extension prend automatiquement en charge la gestion du fichier dans l’interface utilisateur. Sélectionnez le bouton Ajouter une nouvelle ressource. Suivez les instructions pour ajouter une entrée pour Greeting (clé), ¡Hola, Mundo! (valeur) et None (commentaire). Enregistrez le fichier. Si vous fermez et rouvrez le fichier, vous pouvez voir la ressource Greeting.

L’exemple suivant illustre un fichier de ressources standard. Vous pouvez placer manuellement les fichiers de ressources dans le dossier Pages de l’application si vous préférez ne pas utiliser d’outils intégrés avec un environnement de développement intégré (IDE), tel que l’éditeur de fichiers de ressources intégré de Visual Studio ou Visual Studio Code avec une extension pour créer et éditer des fichiers de ressources.

Pages/CultureExample2.es.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Greeting" xml:space="preserve">
    <value>¡Hola, Mundo!</value>
  </data>
</root>

Le composant suivant illustre l’utilisation de la chaîne localisée Greeting avec IStringLocalizer<T>. Le balisage Razor @Loc["Greeting"] de l’exemple suivant localise la chaîne clé de la valeur Greeting, qui est définie dans les fichiers de ressources précédents.

Ajoutez l’espace de noms pour Microsoft.Extensions.Localization au fichier _Imports.razor de l’application :

@using Microsoft.Extensions.Localization

CultureExample2.razor:

@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc

<h1>Culture Example 2</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Greeting</h2>

<p>
    @Loc["Greeting"]
</p>

<p>
    @greeting
</p>

@code {
    private string? greeting;

    protected override void OnInitialized()
    {
        greeting = Loc["Greeting"];
    }
}

Si vous le souhaitez, ajoutez un élément de menu pour le composant CultureExample2 à la navigation pour le composant NavMenu (NavMenu.razor).

Source de référence du fournisseur de culture WebAssembly

Pour mieux comprendre comment le framework Blazor traite la localisation, consultez la classe WebAssemblyCultureProvider dans la source de référence ASP.NET Core.

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Ressources partagées

Pour créer des ressources partagées de localisation, adoptez l’approche suivante.

  • Créez une classe factice avec un nom de classe arbitraire. Dans l’exemple suivant :

    • L’application utilise l’espace de noms BlazorSample et les ressources de localisation utilisent l’espace de noms BlazorSample.Localization.
    • La classe factice est nommée SharedResource.
    • Le fichier de classe est placé dans un dossier Localization à la racine de l’application.

    Localization/SharedResource.cs:

    namespace BlazorSample.Localization;
    
    public class SharedResource
    {
    }
    
  • Créez les fichiers de ressources partagées avec une Action de génération de Embedded resource. Dans l’exemple suivant :

    • Les fichiers sont placés dans le dossier Localization avec la classe SharedResource factice (Localization/SharedResource.cs).

    • Nommez les fichiers de ressources pour qu’ils correspondent au nom de la classe factice. Les exemples de fichiers suivants incluent un fichier de localisation par défaut et un fichier pour la localisation en espagnol (es).

    • Localization/SharedResource.resx

    • Localization/SharedResource.es.resx

    Avertissement

    Lorsque vous suivez l’approche de cette section, vous ne pouvez pas définir simultanément LocalizationOptions.ResourcesPath et utiliser IStringLocalizerFactory.Create pour charger des ressources.

  • Pour référencer la classe factice pour un IStringLocalizer<T> injecté dans un composant Razor, placez une directive @using pour l’espace de noms de localisation ou incluez l’espace de noms de localisation dans la référence de classe factice. Dans les exemples suivants :

    • Le premier exemple indique l’espace de noms Localization pour la classe factice SharedResource avec une directive @using.
    • Le deuxième exemple indique explicitement l’espace de noms de la classe factice SharedResource.

    Dans un composant Razor, utilisez l’une des approches suivantes :

    @using Localization
    @inject IStringLocalizer<SharedResource> Loc
    
    @inject IStringLocalizer<Localization.SharedResource> Loc
    

Pour plus d’instructions, consultez Globalisation et localisation dans ASP.NET Core.

Remplacement de localisation en utilisant le volet « Capteurs » dans les outils de développement

Lorsque vous utilisez le remplacement de localisation en tirant parti du volet Capteurs dans les outils de développement Google Chrome ou Microsoft Edge, le langage de secours est réinitialisé après le prérendu. Évitez de définir le langage en utilisant le volet Capteurs lors de tests. Définissez le langage en tirant parti des paramètres de langage du navigateur.

Pour obtenir plus d’informations, consultez Blazor La localisation ne fonctionne pas avec InteractiveServer (dotnet/aspnetcore #53707).

Ressources supplémentaires