Blazor ASP.NET Core la globalisation et la localisation

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

Pour la globalisation, Blazor fournit une mise en forme de numéro et de date. Pour la localisation, Blazor restitue le contenu à l’aide du système de ressources .NET.

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

✔️ IStringLocalizer et IStringLocalizer<T> sont pris en charge dans les Blazor applications.

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

Cet article explique comment utiliser Blazorles fonctionnalités de globalisation et de localisation basées sur :

  • En-têteAccept-Language, qui est défini par le navigateur en fonction des préférences linguistiques d’un utilisateur dans les paramètres du navigateur.
  • Culture définie par l’application non basée sur la valeur de l’en-têteAccept-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 obtenir des informations générales supplémentaires, consultez les ressources suivantes :

Remarque

Souvent, les termes langue et culture sont utilisés indifféremment lors de la gestion des concepts de globalisation et de localisation.

Dans cet article, la 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 du navigateur dans l’en-têteAccept-Language. Les paramètres du navigateur utilisent généralement le mot « language » dans l’interface utilisateur.

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

Globalisation

La @bind directive d’attribut applique des formats et analyse les valeurs pour l’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 @bind:culture paramètre 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 System.Globalization.CultureInfo.CurrentCulture propriété .

CultureInfo.InvariantCulture est utilisé pour les types de champs suivants (<input type="{TYPE}" />, où l’espace {TYPE} réservé 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 appropriées basées sur le navigateur.
  • Ne peut pas contenir de texte de forme libre.
  • Fournissez des caractéristiques d’interaction utilisateur en fonction de l’implémentation du navigateur.

Lors de l’utilisation des date types de champs et number , la spécification d’une culture avec @bind:culture n’est pas recommandée, car Blazor fournit une prise en charge intégrée pour le rendu des valeurs dans la culture actuelle.

Les types de champs suivants ont des exigences de mise en forme spécifiques et ne sont actuellement pas pris en charge par Blazor , car ils ne sont pas pris en charge par tous les principaux navigateurs :

  • datetime-local
  • month
  • week

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

Globalisation invariante

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 États-Unis anglais (en-US). Définissez la propriété true sur InvariantGlobalization 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 du runtime pour la globalisation (documentation .NET).

Composant de démonstration

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

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 N2 format 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 Shared/NavMenu.razor pour le CultureExample1 composant.

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

L’en-têteAccept-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 États-Unis l’anglais, l’anglais et l’espagnol chilien avec une préférence pour États-Unis anglais ou anglais :

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

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

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

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

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 par utilisateur de préférence de cet article.

Blazor Server les applications sont localisées à l’aide d’intergiciels de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Program.cs :

builder.Services.AddLocalization();

Spécifiez les cultures prises en charge de l’application dans Program.cs immédiatement après l’ajout du middleware de routage au pipeline de traitement. L’exemple suivant configure les cultures prises en charge pour États-Unis l’anglais et l’espagnol chilien :

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

Pour plus d’informations sur la commande de l’intergiciel de localisation dans le pipeline d’intergiciel de Program.cs, consultez ASP.NET Core middleware.

Utilisez le CultureExample1 composant présenté dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettez une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue 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 que vous comprenez, car tous les écrans d’interface utilisateur de paramètre peuvent se retrouver dans une langue que vous ne pouvez pas lire. Un navigateur tel qu’Opera est un bon choix pour les tests, car il vous permet de définir une langue par défaut pour les demandes de page web, mais de laisser l’interface utilisateur des paramètres du navigateur dans votre langue.

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

  • Date : 7/06/2021 06:45:22 AM
  • Nombre : 1 999,69

Lorsque la culture est l’espagnol chilien (es-CL), le composant rendu utilise la mise en forme de date jour/mois (7/6), une heure de 24 heures et des séparateurs de points en nombres avec une virgule pour la valeur décimale (1.999,69) :

  • Date : 06/07/2021 6:49:38
  • Nombre : 1.999,69

Définir statiquement la culture

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

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

La culture de l’application peut être définie en JavaScript quand Blazor commence par l’option applicationCultureBlazor de démarrage. L’exemple suivant configure l’application pour qu’elle démarre à l’aide de la culture États-Unis anglais (en-US).

  • Dans wwwroot/index.html, empêchez le Blazor démarrage automatique en ajoutant autostart="false" à Blazorla balise de <script> :

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Ajoutez le bloc suivant <script> après Blazorla balise de <script> et avant la balise fermante </body> :

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

La valeur de 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 de la culture Blazorconsiste à définir la culture en code C#. Définissez CultureInfo.DefaultThreadCurrentCulture et CultureInfo.DefaultThreadCurrentUICulture dans Program.cs sur la même culture.

Ajoutez l’espace System.Globalization de noms à Program.cs:

using System.Globalization;

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

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

Important

DefaultThreadCurrentCulture Définissez toujours et DefaultThreadCurrentUICulture sur la même culture pour utiliser IStringLocalizer et IStringLocalizer<T>.

Blazor Server les applications sont localisées à l’aide d’intergiciels de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Program.cs :

builder.Services.AddLocalization();

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

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 du middleware de localisation dans le pipeline middleware de Program.cs, consultez ASP.NET Core middleware.

Utilisez le CultureExample1 composant indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol chilien, la culture de l’application reste États-Unis anglais (en-US).

Définir dynamiquement la culture par préférence utilisateur

Exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (courant dans les Blazor Server applications), ou dans 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 Microsoft.Extensions.Localization package à l’application.

Notes

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 BlazorWebAssemblyLoadAllGlobalizationData propriété sur true dans le fichier projet :

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

La culture de l’application dans une Blazor WebAssembly application est définie à l’aide de l’API Blazor de l’infrastructure. La sélection de culture d’un utilisateur peut être conservée dans le stockage local du navigateur.

Dans le fichier après Blazorla wwwroot/index.html balise et <script> avant la balise fermante</body>, fournissez des JS fonctions pour obtenir et définir la sélection de 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 méthodes 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 de Program.cs:

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante de Program.cs :

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

Remplacez la ligne précédente par le code suivant. Le code ajoute Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization et utilise JS l’interopérabilité 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 une valeur par défaut de États-Unis anglais (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

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

if (result != null)
{
    culture = new CultureInfo(result);
}
else
{
    culture = new CultureInfo("en-US");
    await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}

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

await host.RunAsync();

Important

Toujours défini DefaultThreadCurrentCulture et DefaultThreadCurrentUICulture sur la même culture afin d’utiliser IStringLocalizer et IStringLocalizer<T>.

Le composant suivant CultureSelector montre comment effectuer les actions suivantes :

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

Le CultureSelector composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

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

<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("es-CL"),
    };

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var js = (IJSInProcessRuntime)JS;
                js.InvokeVoid("blazorCulture.set", value.Name);

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

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

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

Exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (courant dans les Blazor Server applications), ou dans un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser une localisation cookie.

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

Notes

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.

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

Dans Program.cs :

builder.Services.AddLocalization();

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

Dans Program.cs immédiatement après l’ajout du middleware de routage au pipeline de traitement :

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

app.UseRequestLocalization(localizationOptions);

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

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

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

Pages/_Host.cshtml:

+ @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 du middleware de localisation dans le pipeline middleware de Program.cs, consultez ASP.NET Core middleware.

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

  • Ajoutez des services MVC en appelant AddControllers la collection de services dans Program.cs:

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

    app.MapControllers();
    

    L’exemple suivant montre l’appel à UseEndpoints après l’ajout de la ligne :

    app.MapControllers();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    

Pour fournir une interface utilisateur permettant à un utilisateur de sélectionner une culture, utilisez une approche basée sur la redirection avec une localisation cookie. 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 redirigé 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 pour empêcher les attaques de redirection ouvertes. Pour plus d’informations, consultez Empêcher les attaques de redirection ouvertes dans ASP.NET Core.

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

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

<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("es-CL"),
    };

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

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var uri = new Uri(Navigation.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

À l’intérieur de la balise fermante </main> dans Shared/MainLayout.razor, ajoutez le CultureSelector composant :

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

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

Localisation

Si l’application ne prend pas déjà en charge la sélection de culture conformément à la section Définir dynamiquement la culture par utilisateur de cet article, ajoutez le Microsoft.Extensions.Localization package à l’application.

Notes

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 BlazorWebAssemblyLoadAllGlobalizationData propriété true sur dans le fichier projet de l’application (.csproj) :

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

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

using System.Globalization;

Ajoutez Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization dans Program.cs:

builder.Services.AddLocalization();

Utilisez le middleware 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 conformément à la section Définir dynamiquement la préférence de culture par utilisateur de cet article :

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

Dans Program.cs :

builder.Services.AddLocalization();

Dans Program.cs immédiatement après l’ajout du middleware de routage au pipeline de traitement :

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

app.UseRequestLocalization(localizationOptions);

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

Si l’application doit localiser des ressources en fonction du stockage du paramètre de culture d’un utilisateur, utilisez une culture cookiede 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, ce qui ne permet pas de conserver la culture. Par conséquent, l’approche recommandée consiste à utiliser une culture cookiede localisation . Consultez la section Définir dynamiquement la culture par préférence utilisateur de cet article pour voir un exemple Razor d’expression qui conserve la sélection de culture de l’utilisateur.

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ètres régionaux par défaut et l’espagnol (es) en tant que paramètres régionaux alternatifs sélectionnables par l’utilisateur ou spécifiés par le navigateur.

Créez des ressources pour chaque paramètre régional. Dans l’exemple suivant, des ressources sont créées pour une chaîne par défaut Greeting :

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

Remarque

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. 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 valeurHello, World!sur . Enregistrez le fichier .

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>

Notes

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. 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¡Hola, Mundo!sur . Enregistrez le fichier .

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 Razor balisage @Loc["Greeting"] de l’exemple suivant localise la chaîne clé sur la Greeting valeur, qui est définie dans les fichiers de ressources précédents.

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

@using Microsoft.Extensions.Localization

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 à la navigation dans Shared/NavMenu.razor pour le CultureExample2 composant.

Source de référence du fournisseur de culture

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

Notes

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 BlazorSample de noms et les ressources de localisation utilisent l’espace de BlazorSample.Localization noms.
    • La classe factice est nommée SharedResource.
    • Le fichier de classe est placé dans un Localization dossier à 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 Localization dossier avec la classe factice SharedResource (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

    Remarque

    Localization est le chemin de ressource qui peut être défini via LocalizationOptions.

  • Pour référencer la classe factice d’un injecté IStringLocalizer<T> dans un Razor composant, placez une @using directive 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 Localization de noms de la SharedResource classe factice avec une @using directive.
    • Le deuxième exemple indique explicitement l’espace de noms de la SharedResource classe factice.

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

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

Pour obtenir des conseils supplémentaires, consultez Globalisation et localisation dans ASP.NET Core.

Ressources supplémentaires

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 de ASP.NET Core sont prises en charge :

✔️ IStringLocalizer et IStringLocalizer<T> sont pris en charge dans les Blazor applications.

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

Cet article explique comment utiliser Blazorles fonctionnalités de globalisation et de localisation basées sur :

  • En-têteAccept-Language, qui est défini par le navigateur en fonction des préférences linguistiques d’un utilisateur dans les paramètres du navigateur.
  • Culture définie par l’application qui n’est pas basée sur la valeur de l’en-têteAccept-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 plus d’informations générales, consultez les ressources suivantes :

Remarque

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, la 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 demandes de navigateur dans l’en-têteAccept-Language. Les paramètres du navigateur utilisent généralement le mot « language » dans l’interface utilisateur.

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

Globalisation

La @bind directive attribut applique des formats et analyse les valeurs pour l’affichage en fonction du premier langage préféré de l’utilisateur pris en charge par l’application. @bind prend en charge le @bind:culture paramètre 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 System.Globalization.CultureInfo.CurrentCulture propriété .

CultureInfo.InvariantCulture est utilisé pour les types de champs suivants (<input type="{TYPE}" />, où l’espace {TYPE} réservé 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 peut pas contenir de texte de forme libre.
  • Fournissez des caractéristiques d’interaction utilisateur en fonction de l’implémentation du navigateur.

Lors de l’utilisation des date types de champs et number , la spécification d’une culture avec @bind:culture n’est pas recommandée, car Blazor fournit une prise en charge intégrée pour afficher les valeurs dans la culture actuelle.

Les types de champs suivants ont des exigences de mise en forme spécifiques et ne sont actuellement pas pris en charge par Blazor , car ils ne sont pas pris en charge par tous les principaux navigateurs :

  • datetime-local
  • month
  • week

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

Mondialisation invariante

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 États-Unis anglais (en-US). Définissez la InvariantGlobalization propriété true sur dans le fichier projet de l’application (.csproj) :

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

Vous pouvez également configurer la mondialisation 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).

Composant de démonstration

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

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 N2 format 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 Shared/NavMenu.razor pour le CultureExample1 composant.

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

L’en-têteAccept-Language est défini par le navigateur et contrôlé par les préférences de langue 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é (q0-1) pour chaque langue de l’en-tête. L’exemple suivant spécifie États-Unis l’anglais, l’anglais et l’espagnol chilien avec une préférence pour États-Unis anglais ou 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.

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

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

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 par préférence utilisateur de cet article.

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

Dans Program.cs :

builder.Services.AddLocalization();

Spécifiez les cultures prises en charge de l’application immédiatement Program.cs après l’ajout du middleware de routage au pipeline de traitement. L’exemple suivant configure les cultures prises en charge pour États-Unis l’anglais et l’espagnol chilien :

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

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

Utilisez le CultureExample1 composant indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web.

Remarque

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

Lorsque la culture est États-Unis anglais (en-US), le composant rendu utilise la mise en forme de la date mois/jour (6/7), une heure de 12 heures (PMAM/) et des séparateurs de virgules en nombres avec un point pour la valeur décimale () :1,999.69

  • Date : 7/06/2021 6:45:22 AM
  • Nombre : 1 999,69

Lorsque la culture est l’espagnol chilien (es-CL), le composant rendu utilise la mise en forme de la date jour/mois (7/6), une heure de 24 heures et des séparateurs de période en nombres avec une virgule pour la valeur décimale (1.999,69) :

  • Date : 6/07/2021 6:49:38
  • Nombre : 1.999,69

Définir statiquement la culture

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

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

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

  • Dans wwwroot/index.html, empêchez le Blazor démarrage automatique en ajoutant autostart="false" à Blazorla balise de <script> :

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Ajoutez le bloc suivant <script> après Blazorla balise de <script> et avant la balise fermante </body> :

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

La valeur de 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 de la culture Blazorconsiste à définir la culture en code C#. Définissez CultureInfo.DefaultThreadCurrentCulture et CultureInfo.DefaultThreadCurrentUICulture dans Program.cs sur la même culture.

Ajoutez l’espace System.Globalization de noms à Program.cs:

using System.Globalization;

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

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

Important

Toujours défini DefaultThreadCurrentCulture et DefaultThreadCurrentUICulture sur la même culture afin d’utiliser IStringLocalizer et IStringLocalizer<T>.

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

Dans Program.cs :

builder.Services.AddLocalization();

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

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 du middleware de localisation dans le pipeline middleware de Program.cs, consultez ASP.NET Core middleware.

Utilisez le CultureExample1 composant indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol chilien, la culture de l’application reste États-Unis anglais (en-US).

Définir dynamiquement la culture par préférence utilisateur

Exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (courant dans les Blazor Server applications), ou dans 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 Microsoft.Extensions.Localization package à l’application.

Notes

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 BlazorWebAssemblyLoadAllGlobalizationData propriété sur true dans le fichier projet :

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

La culture de l’application dans une Blazor WebAssembly application est définie à l’aide de l’API Blazor de l’infrastructure. La sélection de culture d’un utilisateur peut être conservée dans le stockage local du navigateur.

Dans le fichier après Blazorla wwwroot/index.html balise et <script> avant la balise fermante</body>, fournissez des JS fonctions pour obtenir et définir la sélection de 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 méthodes 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 de Program.cs:

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante de Program.cs :

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

Remplacez la ligne précédente par le code suivant. Le code ajoute Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization et utilise JS l’interopérabilité 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 une valeur par défaut de États-Unis anglais (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

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

if (result != null)
{
    culture = new CultureInfo(result);
}
else
{
    culture = new CultureInfo("en-US");
    await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}

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

await host.RunAsync();

Important

Toujours défini DefaultThreadCurrentCulture et DefaultThreadCurrentUICulture sur la même culture afin d’utiliser IStringLocalizer et IStringLocalizer<T>.

Le composant suivant CultureSelector montre comment effectuer les actions suivantes :

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

Le CultureSelector composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

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

<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("es-CL"),
    };

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var js = (IJSInProcessRuntime)JS;
                js.InvokeVoid("blazorCulture.set", value.Name);

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

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

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

Exemples d’emplacements où une application peut stocker les préférences d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (courant dans les Blazor Server applications), ou dans un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser une localisation cookie.

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

Notes

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.

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

Dans Program.cs :

builder.Services.AddLocalization();

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

Dans Program.cs immédiatement après l’ajout du middleware de routage au pipeline de traitement :

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

app.UseRequestLocalization(localizationOptions);

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

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

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

Pages/_Host.cshtml:

@page "/"
@namespace {NAMESPACE}.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
    Layout = "_Layout";
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

<component type="typeof(App)" render-mode="ServerPrerendered" />

Dans l’exemple précédent, l’espace {NAMESPACE} réservé est le nom de l’assembly de l’application.

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

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

  • Ajoutez des services MVC en appelant AddControllers la collection de services dans Program.cs:

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

    app.MapControllers();
    

    L’exemple suivant montre l’appel à UseEndpoints après l’ajout de la ligne :

    app.MapControllers();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    

Pour fournir une interface utilisateur permettant à un utilisateur de sélectionner une culture, utilisez une approche basée sur la redirection avec une localisation cookie. 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 redirigé 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 pour empêcher les attaques de redirection ouvertes. Pour plus d’informations, consultez Empêcher les attaques de redirection ouvertes dans ASP.NET Core.

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

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

<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("es-CL"),
    };

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

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var uri = new Uri(Navigation.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

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

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

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

Localisation

Si l’application ne prend pas déjà en charge la sélection de culture conformément à la section Définir dynamiquement la culture par utilisateur de cet article, ajoutez le Microsoft.Extensions.Localization package à l’application.

Notes

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 BlazorWebAssemblyLoadAllGlobalizationData propriété true sur dans le fichier projet de l’application (.csproj) :

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

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

using System.Globalization;

Ajoutez Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization dans Program.cs:

builder.Services.AddLocalization();

Utilisez le middleware 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 conformément à la section Définir dynamiquement la préférence de culture par utilisateur de cet article :

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

Dans Program.cs :

builder.Services.AddLocalization();

Dans Program.cs immédiatement après l’ajout du middleware de routage au pipeline de traitement :

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

app.UseRequestLocalization(localizationOptions);

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

Si l’application doit localiser des ressources en fonction du stockage du paramètre de culture d’un utilisateur, utilisez une culture cookiede 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, ce qui ne permet pas de conserver la culture. Par conséquent, l’approche recommandée consiste à utiliser une culture cookiede localisation . Consultez la section Définir dynamiquement la culture par préférence utilisateur de cet article pour voir un exemple Razor d’expression qui conserve la sélection de culture de l’utilisateur.

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ètres régionaux par défaut et l’espagnol (es) en tant que paramètres régionaux alternatifs sélectionnables par l’utilisateur ou spécifiés par le navigateur.

Créez des ressources pour chaque paramètre régional. Dans l’exemple suivant, des ressources sont créées pour une chaîne par défaut Greeting :

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

Remarque

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. 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 valeurHello, World!sur . Enregistrez le fichier .

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>

Notes

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. 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¡Hola, Mundo!sur . Enregistrez le fichier .

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 Razor balisage @Loc["Greeting"] de l’exemple suivant localise la chaîne clé sur la Greeting valeur, qui est définie dans les fichiers de ressources précédents.

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

@using Microsoft.Extensions.Localization

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 à la navigation dans Shared/NavMenu.razor pour le CultureExample2 composant.

Source de référence du fournisseur de culture

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

Notes

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 BlazorSample de noms et les ressources de localisation utilisent l’espace de BlazorSample.Localization noms.
    • La classe factice est nommée SharedResource.
    • Le fichier de classe est placé dans un Localization dossier à 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 Localization dossier avec la classe factice SharedResource (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

    Remarque

    Localization est le chemin de ressource qui peut être défini via LocalizationOptions.

  • Pour référencer la classe factice d’un injecté IStringLocalizer<T> dans un Razor composant, placez une @using directive 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 Localization de noms de la SharedResource classe factice avec une @using directive.
    • Le deuxième exemple indique explicitement l’espace de noms de la SharedResource classe factice.

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

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

Pour obtenir des conseils supplémentaires, consultez Globalisation et localisation dans ASP.NET Core.

Ressources supplémentaires

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 de ASP.NET Core sont prises en charge :

✔️ IStringLocalizer et IStringLocalizer<T> sont pris en charge dans les Blazor applications.

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

Cet article explique comment utiliser Blazorles fonctionnalités de globalisation et de localisation basées sur :

  • En-têteAccept-Language, qui est défini par le navigateur en fonction des préférences linguistiques d’un utilisateur dans les paramètres du navigateur.
  • Culture définie par l’application qui n’est pas basée sur la valeur de l’en-têteAccept-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 plus d’informations générales, consultez les ressources suivantes :

Remarque

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, la 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 demandes de navigateur dans l’en-têteAccept-Language. Les paramètres du navigateur utilisent généralement le mot « language » dans l’interface utilisateur.

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

Globalisation

La @bind directive d’attribut applique des formats et analyse les valeurs pour l’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 @bind:culture paramètre 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 System.Globalization.CultureInfo.CurrentCulture propriété .

CultureInfo.InvariantCulture est utilisé pour les types de champs suivants (<input type="{TYPE}" />, où l’espace {TYPE} réservé 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 appropriées basées sur le navigateur.
  • Ne peut pas contenir de texte de forme libre.
  • Fournissez des caractéristiques d’interaction utilisateur en fonction de l’implémentation du navigateur.

Lors de l’utilisation des date types de champs et number , la spécification d’une culture avec @bind:culture n’est pas recommandée, car Blazor fournit une prise en charge intégrée pour le rendu des valeurs dans la culture actuelle.

Les types de champs suivants ont des exigences de mise en forme spécifiques et ne sont actuellement pas pris en charge par Blazor , car ils ne sont pas pris en charge par tous les principaux navigateurs :

  • datetime-local
  • month
  • week

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

Globalisation invariante

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 États-Unis anglais (en-US). Définissez la propriété true sur InvariantGlobalization 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 du runtime pour la globalisation (documentation .NET).

Composant de démonstration

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

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 N2 format 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 Shared/NavMenu.razor pour le CultureExample1 composant.

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

L’en-têteAccept-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 États-Unis l’anglais, l’anglais et l’espagnol chilien avec une préférence pour États-Unis anglais ou anglais :

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

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

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

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

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 par utilisateur de préférence de cet article.

Blazor Server les applications sont localisées à l’aide d’intergiciels de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

Spécifiez les cultures prises en charge de l’application dans Startup.Configure (Startup.cs) immédiatement après l’ajout du middleware de routage au pipeline de traitement. L’exemple suivant configure les cultures prises en charge pour États-Unis l’anglais et l’espagnol chilien :

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

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

Utilisez le CultureExample1 composant présenté dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettez une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue 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 que vous comprenez, car tous les écrans d’interface utilisateur de paramètre peuvent se retrouver dans une langue que vous ne pouvez pas lire. Un navigateur tel qu’Opera est un bon choix pour les tests, car il vous permet de définir une langue par défaut pour les demandes de page web, mais de laisser l’interface utilisateur des paramètres du navigateur dans votre langue.

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

  • Date : 7/06/2021 06:45:22 AM
  • Nombre : 1 999,69

Lorsque la culture est l’espagnol chilien (es-CL), le composant rendu utilise la mise en forme de date jour/mois (7/6), une heure de 24 heures et des séparateurs de points en nombres avec une virgule pour la valeur décimale (1.999,69) :

  • Date : 06/07/2021 6:49:38
  • Nombre : 1.999,69

Définir statiquement la culture

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

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

La culture de l’application peut être définie en JavaScript quand Blazor commence par l’option applicationCultureBlazor de démarrage. L’exemple suivant configure l’application pour qu’elle démarre à l’aide de la culture États-Unis anglais (en-US).

  • Dans wwwroot/index.html, empêchez le Blazor démarrage automatique en ajoutant autostart="false" à Blazorla balise de <script> :

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Ajoutez le bloc suivant <script> après Blazorla balise de <script> et avant la balise fermante </body> :

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

La valeur de 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 de la culture Blazorconsiste à définir la culture en code C#. Définissez CultureInfo.DefaultThreadCurrentCulture et CultureInfo.DefaultThreadCurrentUICulture dans Program.cs sur la même culture.

Ajoutez l’espace System.Globalization de noms à Program.cs:

using System.Globalization;

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

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

Important

DefaultThreadCurrentCulture Définissez toujours et DefaultThreadCurrentUICulture sur la même culture pour utiliser IStringLocalizer et IStringLocalizer<T>.

Blazor Server les applications sont localisées à l’aide d’intergiciels 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 du middleware de routage au pipeline de traitement. L’exemple suivant configure États-Unis anglais :

app.UseRequestLocalization("en-US");

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

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

Utilisez le CultureExample1 composant présenté dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettez une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol chilien, la culture de l’application reste États-Unis anglais (en-US).

Définir dynamiquement la culture par préférence utilisateur

Les exemples d’emplacements où une application peut stocker la préférence d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (commune dans Blazor Server les applications) ou dans 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 Microsoft.Extensions.Localization package à l’application.

Notes

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 BlazorWebAssemblyLoadAllGlobalizationData propriété true sur dans le fichier projet :

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

La culture de l’application dans une Blazor WebAssembly application est définie à l’aide de l’API Blazor du framework. La sélection de la culture d’un utilisateur peut être conservée dans le stockage local du navigateur.

Dans le fichier après Blazorla wwwroot/index.html balise et <script> avant la balise de fermeture</body>, fournissez des JS fonctions pour obtenir et définir la sélection de 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 méthodes 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 de Program.cs:

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante de Program.cs :

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

Remplacez la ligne précédente par le code suivant. Le code ajoute Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization et utilise JS l’interopérabilité 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 une valeur par défaut États-Unis anglais (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

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

if (result != null)
{
    culture = new CultureInfo(result);
}
else
{
    culture = new CultureInfo("en-US");
    await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}

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

await host.RunAsync();

Important

DefaultThreadCurrentCulture Définissez toujours et DefaultThreadCurrentUICulture sur la même culture pour utiliser IStringLocalizer et IStringLocalizer<T>.

Le composant suivant CultureSelector montre comment définir la sélection de la culture de l’utilisateur dans le stockage local du navigateur via JS l’interopérabilité. Le composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

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

<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("es-CL"),
    };

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var js = (IJSInProcessRuntime)JS;
                js.InvokeVoid("blazorCulture.set", value.Name);

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

Dans la balise de fermeture </div> de l’élément <div class="main"> dans Shared/MainLayout.razor, ajoutez le CultureSelector composant :

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

Les exemples d’emplacements où une application peut stocker la préférence d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (commune dans Blazor Server les applications) ou dans un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser une localisation cookie.

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

Notes

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.

Blazor Server les applications sont localisées à l’aide d’intergiciels de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

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

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

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

app.UseRequestLocalization(localizationOptions);

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

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

Ajoutez les espaces de noms suivants en haut du Pages/_Host.cshtml fichier :

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

Immédiatement après la balise d’ouverture <body> de Pages/_Host.cshtml, ajoutez l’expression suivante Razor :

@{
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

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

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 Startup.ConfigureServices:

    services.AddControllers();
    
  • Ajoutez le routage du point de terminaison de contrôleur dans en Startup.Configure appelant MapControllers sur le IEndpointRouteBuilder:

    endpoints.MapControllers();
    

    L’exemple suivant montre l’appel à UseEndpoints après l’ajout de la ligne :

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
    

Pour fournir une interface utilisateur permettant à un utilisateur de sélectionner une culture, utilisez une approche basée sur la redirection avec une localisation cookie. 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 le redirige vers l’URI d’origine. Le processus est similaire à ce qui se passe 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 redirigé 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 pour empêcher les attaques de redirection ouverte. Pour plus d’informations, consultez Empêcher les attaques de redirection ouverte dans ASP.NET Core.

Le composant suivant CultureSelector montre comment effectuer la redirection initiale lorsque l’utilisateur sélectionne une culture. Le composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

<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("es-CL"),
    };

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

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var uri = new Uri(Navigation.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

Dans la balise de fermeture </div> de l’élément <div class="main"> dans Shared/MainLayout.razor, ajoutez le CultureSelector composant :

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

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

Localisation

Si l’application ne prend pas déjà en charge la sélection de culture conformément à la section Définir dynamiquement la culture par préférence utilisateur de cet article, ajoutez le Microsoft.Extensions.Localization package à l’application.

Notes

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é true sur BlazorWebAssemblyLoadAllGlobalizationData dans le fichier projet de l’application (.csproj) :

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

Dans Program.cs, ajoutez l’espace de noms pour System.Globalization au début du fichier :

using System.Globalization;

Ajoutez Blazorle service de localisation à la collection de services de l’application avec AddLocalization dans Program.cs:

builder.Services.AddLocalization();

Utilisez le middleware 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 conformément à la section Définir dynamiquement la culture par préférence utilisateur de cet article :

  • 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 États-Unis l’anglais et l’espagnol chilien.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

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

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

app.UseRequestLocalization(localizationOptions);

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

Si l’application doit localiser des ressources en fonction du stockage du paramètre de culture d’un utilisateur, utilisez une culture cookiede 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 les WebSockets, ce qui ne permet pas de conserver la culture. Par conséquent, l’approche recommandée consiste à utiliser une culture cookiede localisation . Consultez la section Définir dynamiquement la culture par préférence utilisateur de cet article pour voir un exemple Razor d’expression pour le Pages/_Host.cshtml fichier qui conserve la sélection de culture de l’utilisateur.

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ètres régionaux par défaut et l’espagnol (es) en tant que paramètres régionaux alternatifs sélectionnables par l’utilisateur ou spécifiés par le navigateur.

Créez des ressources pour chaque paramètre régional. Dans l’exemple suivant, des ressources sont créées pour une chaîne par défaut Greeting :

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

Remarque

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. Nommez le fichier CultureExample2.resx. Lorsque l’éditeur s’affiche, fournissez les données d’une nouvelle entrée. Définissez le nom sur Greeting et la valeur sur Hello, World!. Enregistrez le fichier .

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>

Notes

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. Nommez le fichier CultureExample2.es.resx. Lorsque l’éditeur s’affiche, fournissez les données d’une nouvelle entrée. Définissez le nom sur Greeting et la valeur sur ¡Hola, Mundo!. Enregistrez le fichier .

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 Razor balisage @Loc["Greeting"] de l’exemple suivant localise la chaîne clé sur la Greeting valeur, qui est définie dans les fichiers de ressources précédents.

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

@using Microsoft.Extensions.Localization

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 à la navigation dans Shared/NavMenu.razor pour le CultureExample2 composant.

Source de référence du fournisseur de culture

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

Notes

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 BlazorSample de noms et les ressources de localisation utilisent l’espace de BlazorSample.Localization noms.
    • La classe factice est nommée SharedResource.
    • Le fichier de classe est placé dans un Localization dossier à la racine de l’application.

    Localization/SharedResource.cs:

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

    • Les fichiers sont placés dans le Localization dossier avec la classe factice SharedResource (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

    Remarque

    Localization est le chemin de ressource qui peut être défini via LocalizationOptions.

  • Pour référencer la classe factice d’un injecté IStringLocalizer<T> dans un Razor composant, placez une @using directive 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 Localization de noms de la SharedResource classe factice avec une @using directive.
    • Le deuxième exemple indique explicitement l’espace de noms de la SharedResource classe factice.

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

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

Pour obtenir des conseils supplémentaires, consultez Globalisation et localisation dans ASP.NET Core.

Ressources supplémentaires

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 de ASP.NET Core sont prises en charge :

✔️ IStringLocalizer et IStringLocalizer<T> sont pris en charge dans les Blazor applications.

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

Cet article explique comment utiliser Blazorles fonctionnalités de globalisation et de localisation basées sur :

  • En-têteAccept-Language, qui est défini par le navigateur en fonction des préférences linguistiques d’un utilisateur dans les paramètres du navigateur.
  • Culture définie par l’application qui n’est pas basée sur la valeur de l’en-têteAccept-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 plus d’informations générales, consultez les ressources suivantes :

Remarque

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, la 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 demandes de navigateur dans l’en-têteAccept-Language. Les paramètres du navigateur utilisent généralement le mot « language » dans l’interface utilisateur.

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

Globalisation

La @bind directive attribut applique des formats et analyse les valeurs pour l’affichage en fonction du premier langage préféré de l’utilisateur pris en charge par l’application. @bind prend en charge le @bind:culture paramètre 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 System.Globalization.CultureInfo.CurrentCulture propriété .

CultureInfo.InvariantCulture est utilisé pour les types de champs suivants (<input type="{TYPE}" />, où l’espace {TYPE} réservé 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 peut pas contenir de texte de forme libre.
  • Fournissez des caractéristiques d’interaction utilisateur en fonction de l’implémentation du navigateur.

Lors de l’utilisation des date types de champs et number , la spécification d’une culture avec @bind:culture n’est pas recommandée, car Blazor fournit une prise en charge intégrée pour afficher les valeurs dans la culture actuelle.

Les types de champs suivants ont des exigences de mise en forme spécifiques et ne sont actuellement pas pris en charge par Blazor , car ils ne sont pas pris en charge par tous les principaux navigateurs :

  • datetime-local
  • month
  • week

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

Mondialisation invariante

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 États-Unis anglais (en-US). Définissez la InvariantGlobalization propriété true sur dans le fichier projet de l’application (.csproj) :

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

Vous pouvez également configurer la mondialisation 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).

Composant de démonstration

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

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 N2 format 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 Shared/NavMenu.razor pour le CultureExample1 composant.

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

L’en-têteAccept-Language est défini par le navigateur et contrôlé par les préférences de langue 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é (q0-1) pour chaque langue de l’en-tête. L’exemple suivant spécifie États-Unis l’anglais, l’anglais et l’espagnol chilien avec une préférence pour États-Unis anglais ou 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.

Blazor Server les applications 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 les cultures prises en charge de l’application dans Startup.Configure (Startup.cs) immédiatement après l’ajout du middleware de routage au pipeline de traitement. L’exemple suivant configure les cultures prises en charge pour États-Unis l’anglais et l’espagnol chilien :

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

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

Utilisez le CultureExample1 composant indiqué dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettre une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web.

Remarque

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

Lorsque la culture est États-Unis anglais (en-US), le composant rendu utilise la mise en forme de la date mois/jour (6/7), une heure de 12 heures (PMAM/) et des séparateurs de virgules en nombres avec un point pour la valeur décimale () :1,999.69

  • Date : 7/06/2021 6:45:22 AM
  • Nombre : 1 999,69

Lorsque la culture est l’espagnol chilien (es-CL), le composant rendu utilise la mise en forme de la date jour/mois (7/6), une heure de 24 heures et des séparateurs de période en nombres avec une virgule pour la valeur décimale (1.999,69) :

  • Date : 6/07/2021 6:49:38
  • Nombre : 1.999,69

Définir statiquement la culture

Par défaut, la configuration de l’éditeur de liens en langage intermédiaire (IL) pour Blazor WebAssembly les applications 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.

Blazor Server les applications 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 du middleware de routage au pipeline de traitement. L’exemple suivant configure États-Unis anglais :

app.UseRequestLocalization("en-US");

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

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

Utilisez le CultureExample1 composant présenté dans la section Composant de démonstration pour étudier le fonctionnement de la globalisation. Émettez une demande avec États-Unis anglais (en-US). Basculez vers l’espagnol chilien (es-CL) dans les paramètres de langue du navigateur. Demandez à nouveau la page web. Lorsque la langue demandée est l’espagnol chilien, la culture de l’application reste États-Unis anglais (en-US).

Définir dynamiquement la culture par préférence utilisateur

Les exemples d’emplacements où une application peut stocker la préférence d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (commune dans Blazor Server les applications) ou dans 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 Microsoft.Extensions.Localization package à l’application.

Notes

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.

La culture de l’application dans une Blazor WebAssembly application est définie à l’aide de l’API Blazor du framework. La sélection de la culture d’un utilisateur peut être conservée dans le stockage local du navigateur.

Dans le fichier après Blazorla wwwroot/index.html balise et <script> avant la balise de fermeture</body>, fournissez des JS fonctions pour obtenir et définir la sélection de culture de l’utilisateur avec le stockage local du navigateur :

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

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

using System.Globalization;
using Microsoft.JSInterop;

Supprimez la ligne suivante de Program.cs :

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

Remplacez la ligne précédente par le code suivant. Le code ajoute Blazorle service de localisation de l’application à la collection de services de l’application avec AddLocalization et utilise JS l’interopérabilité 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 une valeur par défaut États-Unis anglais (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

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

if (result != null)
{
    culture = new CultureInfo(result);
}
else
{
    culture = new CultureInfo("en-US");
    await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}

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

await host.RunAsync();

Important

DefaultThreadCurrentCulture Définissez toujours et DefaultThreadCurrentUICulture sur la même culture pour utiliser IStringLocalizer et IStringLocalizer<T>.

Le composant suivant CultureSelector montre comment définir la sélection de la culture de l’utilisateur dans le stockage local du navigateur via JS l’interopérabilité. Le composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

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

<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("es-CL"),
    };

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var js = (IJSInProcessRuntime)JS;
                js.InvokeVoid("blazorCulture.set", value.Name);

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

Dans la balise de fermeture </div> de l’élément <div class="main"> dans Shared/MainLayout.razor, ajoutez le CultureSelector composant :

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

Les exemples d’emplacements où une application peut stocker la préférence d’un utilisateur incluent dans le stockage local du navigateur (courant dans les Blazor WebAssembly applications), dans une localisation cookie ou une base de données (commune dans Blazor Server les applications) ou dans un service externe attaché à une base de données externe et accessible par une API web. L’exemple suivant montre comment utiliser une localisation cookie.

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

Notes

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.

Blazor Server les applications sont localisées à l’aide d’intergiciels de localisation. Ajoutez des services de localisation à l’application avec AddLocalization.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

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

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

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

app.UseRequestLocalization(localizationOptions);

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

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

Ajoutez les espaces de noms suivants en haut du Pages/_Host.cshtml fichier :

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

Immédiatement après la balise d’ouverture <body> de Pages/_Host.cshtml, ajoutez l’expression suivante Razor :

@{
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

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

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 Startup.ConfigureServices:

    services.AddControllers();
    
  • Ajoutez le routage du point de terminaison de contrôleur dans en Startup.Configure appelant MapControllers sur le IEndpointRouteBuilder:

    endpoints.MapControllers();
    

    L’exemple suivant montre l’appel à UseEndpoints après l’ajout de la ligne :

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
    

Pour fournir une interface utilisateur permettant à un utilisateur de sélectionner une culture, utilisez une approche basée sur la redirection avec une localisation cookie. 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 le redirige vers l’URI d’origine. Le processus est similaire à ce qui se passe 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 redirigé 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 pour empêcher les attaques de redirection ouverte. Pour plus d’informations, consultez Empêcher les attaques de redirection ouverte dans ASP.NET Core.

Le composant suivant CultureSelector montre comment effectuer la redirection initiale lorsque l’utilisateur sélectionne une culture. Le composant est placé dans le Shared dossier pour une utilisation dans l’ensemble de l’application.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

<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("es-CL"),
    };

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

    private CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var uri = new Uri(Navigation.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

Dans la balise de fermeture </div> de l’élément <div class="main"> dans Shared/MainLayout.razor, ajoutez le CultureSelector composant :

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

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

Localisation

Si l’application ne prend pas déjà en charge la sélection de culture conformément à la section Définir dynamiquement la culture par préférence utilisateur de cet article, ajoutez le Microsoft.Extensions.Localization package à l’application.

Notes

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.

Par défaut, la configuration de l’éditeur de liens il (Intermediate Language) pour Blazor WebAssembly les applications 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.

Dans Program.cs, ajoutez l’espace de noms pour System.Globalization au début du fichier :

using System.Globalization;

Ajoutez Blazorle service de localisation à la collection de services de l’application avec AddLocalization dans Program.cs:

builder.Services.AddLocalization();

Utilisez le middleware 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 conformément à la section Définir dynamiquement la culture par préférence utilisateur de cet article :

  • 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 États-Unis l’anglais et l’espagnol chilien.

Dans Startup.ConfigureServices (Startup.cs) :

services.AddLocalization();

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

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

app.UseRequestLocalization(localizationOptions);

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

Si l’application doit localiser des ressources en fonction du stockage du paramètre de culture d’un utilisateur, utilisez une culture cookiede 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 les WebSockets, ce qui ne permet pas de conserver la culture. Par conséquent, l’approche recommandée consiste à utiliser une culture cookiede localisation . Consultez la section Définir dynamiquement la culture par préférence utilisateur de cet article pour voir un exemple Razor d’expression pour le Pages/_Host.cshtml fichier qui conserve la sélection de culture de l’utilisateur.

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ètres régionaux par défaut et l’espagnol (es) en tant que paramètres régionaux alternatifs sélectionnables par l’utilisateur ou spécifiés par le navigateur.

Créez des ressources pour chaque paramètre régional. Dans l’exemple suivant, des ressources sont créées pour une chaîne par défaut Greeting :

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

Remarque

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. Nommez le fichier CultureExample2.resx. Lorsque l’éditeur s’affiche, fournissez les données d’une nouvelle entrée. Définissez le nom sur Greeting et la valeur sur Hello, World!. Enregistrez le fichier .

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>

Notes

Le fichier de ressources suivant peut être ajouté dans Visual Studio en cliquant avec le bouton droit sur le dossier du Pages projet et en sélectionnant Ajouter un> fichier deressourcesd’élément>. Nommez le fichier CultureExample2.es.resx. Lorsque l’éditeur s’affiche, fournissez les données d’une nouvelle entrée. Définissez le nom sur Greeting et la valeur sur ¡Hola, Mundo!. Enregistrez le fichier .

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 Razor balisage @Loc["Greeting"] de l’exemple suivant localise la chaîne clé sur la Greeting valeur, qui est définie dans les fichiers de ressources précédents.

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

@using Microsoft.Extensions.Localization

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
</p>

<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 à la navigation dans Shared/NavMenu.razor pour le CultureExample2 composant.

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 BlazorSample de noms et les ressources de localisation utilisent l’espace de BlazorSample.Localization noms.
    • La classe factice est nommée SharedResource.
    • Le fichier de classe est placé dans un Localization dossier à la racine de l’application.

    Localization/SharedResource.cs:

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

    • Les fichiers sont placés dans le Localization dossier avec la classe factice SharedResource (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

    Remarque

    Localization est un chemin de ressource qui peut être défini via LocalizationOptions.

  • Pour référencer la classe factice d’un injecté IStringLocalizer<T> dans un Razor composant, placez une @using directive 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 Localization de noms de la SharedResource classe factice avec une @using directive.
    • Le deuxième exemple indique explicitement l’espace de noms de la SharedResource classe factice.

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

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

Pour obtenir des conseils supplémentaires, consultez Globalisation et localisation dans ASP.NET Core.

Ressources supplémentaires