Udostępnij za pośrednictwem


ASP.NET Core Blazor globalizacji i lokalizacji

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

W tym artykule wyjaśniono, jak renderować zglobalizowaną i zlokalizowaną zawartość użytkownikom w różnych kulturach i językach.

Globalizacja i lokalizacja

W przypadku globalizacji Blazorzapewnia formatowanie liczb i dat. W przypadku lokalizacjiBlazor renderuje zawartość przy użyciu systemu zasobów platformy .NET.

Obsługiwany jest ograniczony zestaw funkcji lokalizacji ASP.NET Core:

Obsługiwane: IStringLocalizer i IStringLocalizer<T> są obsługiwane w Blazor aplikacjach.

Nieobsługiwane: IHtmlLocalizerlokalizacja adnotacji , IViewLocalizeri danych są ASP.NET podstawowe funkcje MVC i nie są obsługiwane w Blazor aplikacjach.

W tym artykule opisano sposób używania Blazorfunkcji globalizacji i lokalizacji w oparciu o:

  • NagłówekAccept-Language, który jest ustawiany przez przeglądarkę na podstawie preferencji językowych użytkownika w ustawieniach przeglądarki.
  • Kultura ustawiona przez aplikację nie jest oparta na wartości nagłówkaAccept-Language. Ustawienie może być statyczne dla wszystkich użytkowników lub dynamicznych na podstawie logiki aplikacji. Gdy ustawienie jest oparte na preferencjach użytkownika, ustawienie jest zwykle zapisywane do ponownego ładowania podczas przyszłych wizyt.

Aby uzyskać dodatkowe ogólne informacje, zobacz następujące zasoby:

Często terminy język i kultura są używane zamiennie podczas radzenia sobie z globalizacją i koncepcją lokalizacji.

W tym artykule język odnosi się do wyborów dokonanych przez użytkownika w ustawieniach przeglądarki. Wybór języka użytkownika jest przesyłany w żądaniach przeglądarki w nagłówkuAccept-Language. Ustawienia przeglądarki zwykle używają słowa "language" w interfejsie użytkownika.

Kultura dotyczy członków platformy .NET i Blazor interfejsu API. Na przykład żądanie użytkownika może zawierać Accept-Language nagłówek określający język z perspektywy użytkownika, ale aplikacja ostatecznie ustawia CurrentCulture właściwość ("kultura") z języka, którego zażądał użytkownik. Interfejs API zwykle używa słowa "culture" w nazwach elementów członkowskich.

Wskazówki zawarte w tym artykule nie obejmują ustawiania atrybutu języka HTML strony (<html lang="...">), którego używają narzędzia accessiblity. Wartość można ustawić statycznie, przypisując język do lang atrybutu tagu <html> lub w document.documentElement.lang języku JavaScript. Można dynamicznie ustawić wartość document.documentElement.lang z JS międzyoperacją.

Uwaga

Przykłady kodu w tym artykule przyjmują typy odwołań dopuszczających wartość null (NRTs) i statyczną analizę stanu null kompilatora platformy .NET, które są obsługiwane w programie ASP.NET Core na platformie .NET 6 lub nowszym. W przypadku określania wartości docelowej ASP.NET Core 5.0 lub starszej usuń oznaczenie typu null (?) z przykładów artykułu.

Globalizacja

Dyrektywa @bind atrybutu stosuje formaty i analizuje wartości do wyświetlania na podstawie pierwszego preferowanego języka użytkownika obsługiwanego przez aplikację. @bind@bind:culture obsługuje parametr , aby zapewnić System.Globalization.CultureInfo parametr do analizowania i formatowania wartości.

Dostęp do bieżącej System.Globalization.CultureInfo.CurrentCulture kultury można uzyskać z właściwości .

CultureInfo.InvariantCulture jest używany dla następujących typów pól (<input type="{TYPE}" />gdzie {TYPE} symbol zastępczy jest typem):

  • date
  • number

Poprzednie typy pól:

  • Są wyświetlane przy użyciu odpowiednich reguł formatowania opartych na przeglądarce.
  • Nie można zawierać tekstu bez formularza.
  • Podaj charakterystykę interakcji użytkownika na podstawie implementacji przeglądarki.

Blazor Zapewnia wbudowaną obsługę renderowania wartości w bieżącej kulturze. W związku z tym określanie kultury z wartością @bind:culture nie jest zalecane w przypadku używania date typów pól i number .

Następujące typy pól mają określone wymagania dotyczące formatowania i nie są obsługiwane przez wszystkie główne przeglądarki, więc nie są obsługiwane przez Blazorprogram :

  • datetime-local
  • month
  • week

Aby uzyskać bieżącą obsługę poprzednich typów w przeglądarce, zobacz Can I use (Czy mogę użyć).

Obsługa globalizacji platformy .NET i międzynarodowych składników dla standardu Unicode (ICU) (Blazor WebAssembly)

Blazor WebAssembly używa ograniczonego interfejsu API globalizacji i zestawu wbudowanych ustawień regionalnych International Components for Unicode (ICU). Aby uzyskać więcej informacji, zobacz Globalizacja platformy .NET i ICU: ICU w zestawie WebAssembly.

Aby załadować niestandardowy plik danych ICU w celu kontrolowania ustawień regionalnych aplikacji, zobacz Icu globalizacji WASM. Obecnie wymagane jest ręczne kompilowanie niestandardowego pliku danych ICU. Narzędzia .NET w celu ułatwienia procesu tworzenia pliku są planowane dla platformy .NET 9 w listopadzie 2024 r.

Blazor WebAssembly używa ograniczonego interfejsu API globalizacji i zestawu wbudowanych ustawień regionalnych International Components for Unicode (ICU). Aby uzyskać więcej informacji, zobacz Globalizacja platformy .NET i ICU: ICU w zestawie WebAssembly.

Ładowanie niestandardowego podzestawu ustawień regionalnych w aplikacji jest obsługiwane na platformie .NET 8 lub nowszym Blazor WebAssembly . Aby uzyskać więcej informacji, uzyskaj dostęp do tej sekcji dla wersji 8.0 lub nowszej tego artykułu.

Niezmienna globalizacja

Ta sekcja dotyczy tylko scenariuszy po stronie Blazor klienta.

Jeśli aplikacja nie wymaga lokalizacji, skonfiguruj aplikację tak, aby obsługiwała niezmienną kulturę, która jest zwykle oparta na Stany Zjednoczone angielski (en-US). Użycie niezmiennej globalizacji zmniejsza rozmiar pobierania aplikacji i powoduje szybsze uruchamianie aplikacji. InvariantGlobalization Ustaw właściwość na true w pliku projektu aplikacji (.csproj):

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

Alternatywnie skonfiguruj niezmienną globalizację przy użyciu następujących metod:

  • W pliku runtimeconfig.json:

    {
      "runtimeOptions": {
        "configProperties": {
          "System.Globalization.Invariant": true
        }
      }
    }
    
  • Ze zmienną środowiskową:

    • Klucz: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
    • Wartość: true lub 1

Aby uzyskać więcej informacji, zobacz Opcje konfiguracji środowiska uruchomieniowego dla globalizacji (dokumentacja platformy.NET).

Informacje o strefie czasowej

Ta sekcja dotyczy tylko scenariuszy po stronie Blazor klienta.

Przyjęcie niezmiennej globalizacji powoduje tylko używanie nielokalizowanych nazw stref czasowych. Aby przyciąć kod strefy czasowej i dane, co zmniejsza rozmiar pobierania aplikacji i powoduje szybsze uruchamianie aplikacji, zastosuj <InvariantTimezone> właściwość MSBuild z wartością true w pliku projektu aplikacji:

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

Uwaga

<BlazorEnableTimeZoneSupport> zastępuje wcześniejsze <InvariantTimezone> ustawienie. Zalecamy usunięcie <BlazorEnableTimeZoneSupport> ustawienia.

Plik danych jest dołączany w celu poprawienia informacji o strefie czasowej. Jeśli aplikacja nie wymaga tej funkcji, rozważ jej wyłączenie, ustawiając <BlazorEnableTimeZoneSupport> właściwość MSBuild na false w pliku projektu aplikacji:

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

Składnik demonstracyjny

Poniższy CultureExample1 składnik może służyć do zademonstrowania Blazor pojęć globalizacji i lokalizacji objętych tym artykułem.

CultureExample1.razor:

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

<h1>Culture Example 1</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

Format ciągu liczbowego () w poprzednim przykładzie (N2.ToString("N2")) jest standardowym specyfikatorem formatu liczbowego platformy .NET. Format N2 jest obsługiwany dla wszystkich typów liczbowych, zawiera separator grupy i renderuje maksymalnie dwa miejsca dziesiętne.

Opcjonalnie dodaj element menu do nawigacji w składniku NavMenu (NavMenu.razor) dla CultureExample1 składnika.

Dynamiczne ustawianie kultury z nagłówka Accept-Language

Microsoft.Extensions.Localization Dodaj pakiet do aplikacji.

Nagłówek Accept-Language jest ustawiany przez przeglądarkę i kontrolowany przez preferencje językowe użytkownika w ustawieniach przeglądarki. W ustawieniach przeglądarki użytkownik ustawia jeden lub więcej preferowanych języków w kolejności preferencji. Kolejność preferencji jest używana przez przeglądarkę do ustawiania wartości jakości (q0–1) dla każdego języka w nagłówku. Poniższy przykład określa Stany Zjednoczone angielski, angielski i kostarykaański hiszpański z preferencjami dla Stany Zjednoczone angielski lub angielski:

Accept-Language: en-US,en; q=0,9,es-CR; q=0.8

Kultura aplikacji jest ustawiana przez dopasowanie pierwszego żądanego języka zgodnego z obsługiwaną kulturą aplikacji.

W przypadku programowania po stronie klienta ustaw BlazorWebAssemblyLoadAllGlobalizationData właściwość na true w pliku projektu aplikacji po stronie klienta (.csproj):

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

W przypadku programowania po stronie klienta dynamiczne ustawianie kultury z nagłówka Accept-Language nie jest obsługiwane.

Uwaga

Jeśli specyfikacja aplikacji wymaga ograniczenia obsługiwanych kultur do jawnej listy, zobacz sekcję Dynamiczne ustawianie kultury po stronie klienta według preferencji użytkownika w tym artykule.

Aplikacje są zlokalizowane przy użyciu oprogramowania pośredniczącego lokalizacji. Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.

Dodaj następujący wiersz do pliku, w Program którym są zarejestrowane usługi:

builder.Services.AddLocalization();

W programowania po stronie serwera określ obsługiwane kultury aplikacji przed każdym oprogramowaniem pośredniczącym, które może sprawdzić kulturę żądania. Ogólnie rzecz biorąc, umieść oprogramowanie pośredniczące żądań lokalizacji bezpośrednio przed wywołaniem metody MapRazorComponents. W poniższym przykładzie są konfigurowane obsługiwane kultury dla języka angielskiego i kostarykańskiej języka hiszpańskiego Stany Zjednoczone:

W programowania po stronie serwera określ obsługiwane kultury aplikacji bezpośrednio po dodaniu oprogramowania pośredniczącego routingu (UseRouting) do potoku przetwarzania. W poniższym przykładzie są konfigurowane obsługiwane kultury dla języka angielskiego i kostarykańskiej języka hiszpańskiego Stany Zjednoczone:

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

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego Program pliku, zobacz ASP.NET Core Middleware.

CultureExample1 Użyj składnika pokazanego w sekcji Składnik demonstracyjny, aby zbadać, jak działa globalizacja. Wyślij żądanie z Stany Zjednoczone angielski (en-US). Przejdź do kostarykańskiej hiszpańskiej () wes-CR ustawieniach języka przeglądarki. Ponownie zażądaj strony internetowej.

Uwaga

Niektóre przeglądarki wymuszają używanie domyślnego ustawienia języka zarówno dla żądań, jak i ustawień interfejsu użytkownika przeglądarki. Może to sprawić, że zmiana języka z powrotem na ten, który jest zrozumiały jako trudny, ponieważ wszystkie ekrany interfejsu użytkownika ustawień mogą znajdować się w języku, którego nie można odczytać. Przeglądarka, taka jak Opera , jest dobrym wyborem do testowania, ponieważ umożliwia ustawienie domyślnego języka dla żądań stron internetowych, ale pozostaw interfejs użytkownika ustawień przeglądarki w twoim języku.

Gdy kultura jest Stany Zjednoczone angielski (en-US), renderowany składnik używa formatowania daty miesiąca/dnia (6/7/AMPM), 12-godzinnego () i separatorów przecinków w liczbach z kropką dla wartości dziesiętnej ():1,999.69

  • Data: 6/7/2021 6:45:22
  • Liczba: 1999,69

Gdy kultura jest kostarykańskim hiszpańskim (es-CR), renderowany składnik używa formatowania daty dnia/miesiąca (7/6), 24-godzinnego i separatorów kropki w liczbach z przecinkiem dla wartości dziesiętnej (1.999,69):

  • Data: 6.07.2021 6:49:38
  • Numer: 1,999,69

Statyczne ustawianie kultury po stronie klienta

BlazorWebAssemblyLoadAllGlobalizationData Ustaw właściwość na true w pliku projektu aplikacji (.csproj):

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

Konfiguracja konsolidatora języka pośredniego (IL) dla renderowania po stronie klienta usuwa informacje o internacjonalizacji z wyjątkiem ustawień regionalnych jawnie żądanych. Aby uzyskać więcej informacji, zobacz Konfigurowanie konsolidatora dla platformy ASP.NET Core Blazor.

Kulturę aplikacji można ustawić w języku JavaScript po Blazor rozpoczęciu od opcji uruchamiania applicationCultureBlazor . Poniższy przykład umożliwia skonfigurowanie aplikacji do uruchamiania przy użyciu kultury języka angielskiego (en-US) Stany Zjednoczone.

Zapobiegaj Blazor autostartowi przez dodanie autostart="false" tagu do Blazortagu <script>:

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

W poprzednim przykładzie {BLAZOR SCRIPT} symbol zastępczy to ścieżka skryptu Blazor i nazwa pliku. Aby uzyskać informacje o lokalizacji skryptu, zobacz ASP.NET Core project structure (Struktura projektu ASP.NET CoreBlazor).

Dodaj następujący <script> blok poBlazor tagu <script> i przed tagiem zamykającym</body>:

Blazor Web App:

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

Autonomiczny zestaw Blazor WebAssembly:

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

Wartość parametru applicationCulture musi być zgodna z formatem tagu języka BCP-47. Aby uzyskać więcej informacji na temat uruchamiania platformy Blazor, zobacz Uruchamianie platformy ASP.NET Core Blazor.

Alternatywą dla ustawienia opcji uruchamiania kultury Blazorjest ustawienie kultury w kodzie języka C#. Ustaw CultureInfo.DefaultThreadCurrentCulture i CultureInfo.DefaultThreadCurrentUICulture w Program pliku na tę samą kulturę.

System.Globalization Dodaj przestrzeń nazw do Program pliku:

using System.Globalization;

Dodaj ustawienia kultury przed wierszem, który kompiluje i uruchamia WebAssemblyHostBuilder element (await builder.Build().RunAsync();):

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

Uwaga

Blazor WebAssembly Obecnie aplikacje ładują tylko zasoby na podstawie elementu DefaultThreadCurrentCulture. Aby uzyskać więcej informacji, zobacz Blazor WASM opiera się tylko na bieżącej kulturze (bieżąca kultura interfejsu użytkownika nie jest szanowana) (dotnet/aspnetcore #56824).

CultureExample1 Użyj składnika pokazanego w sekcji Składnik demonstracyjny, aby zbadać, jak działa globalizacja. Wyślij żądanie z Stany Zjednoczone angielski (en-US). Przejdź do kostarykańskiej hiszpańskiej () wes-CR ustawieniach języka przeglądarki. Ponownie zażądaj strony internetowej. Gdy żądany język jest kostarykańskim hiszpańskim, kultura aplikacji pozostaje Stany Zjednoczone angielski (en-US).

Statyczne ustawianie kultury po stronie serwera

Aplikacje po stronie serwera są zlokalizowane przy użyciu oprogramowania pośredniczącego lokalizacji. Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.

W pliku Program:

builder.Services.AddLocalization();

Określ kulturę statyczną Program w pliku przed wszelkim oprogramowaniem pośredniczącym, które może sprawdzać kulturę żądania. Ogólnie rzecz biorąc, umieść oprogramowanie pośredniczące lokalizacji żądań bezpośrednio przed MapRazorComponents. Poniższy przykład konfiguruje Stany Zjednoczone angielski:

Określ kulturę statyczną Program w pliku natychmiast po dodaniu oprogramowania pośredniczącego routingu (UseRouting) do potoku przetwarzania. Poniższy przykład konfiguruje Stany Zjednoczone angielski:

app.UseRequestLocalization("en-US");

Wartość kultury musi UseRequestLocalization być zgodna z formatem tagu języka BCP-47.

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego Program pliku, zobacz ASP.NET Core Middleware.

Aplikacje po stronie serwera są zlokalizowane przy użyciu oprogramowania pośredniczącego lokalizacji. Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

Określ kulturę statyczną w programie Startup.Configure (Startup.cs) natychmiast po dodaniu oprogramowania pośredniczącego routingu do potoku przetwarzania. Poniższy przykład konfiguruje Stany Zjednoczone angielski:

app.UseRequestLocalization("en-US");

Wartość kultury musi UseRequestLocalization być zgodna z formatem tagu języka BCP-47.

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego Startup.Configureprogramu , zobacz ASP.NET Core Middleware.

CultureExample1 Użyj składnika pokazanego w sekcji Składnik demonstracyjny, aby zbadać, jak działa globalizacja. Wyślij żądanie z Stany Zjednoczone angielski (en-US). Przejdź do kostarykańskiej hiszpańskiej () wes-CR ustawieniach języka przeglądarki. Ponownie zażądaj strony internetowej. Gdy żądany język jest kostarykańskim hiszpańskim, kultura aplikacji pozostaje Stany Zjednoczone angielski (en-US).

Dynamiczne ustawianie kultury po stronie klienta według preferencji użytkownika

Przykłady lokalizacji, w których aplikacja może przechowywać preferencje użytkownika w magazynie lokalnym przeglądarki (typowe dla scenariuszy po stronie klienta), w lokalizacji cookie lub bazie danych (typowe dla scenariuszy po stronie serwera) lub w zewnętrznej usłudze dołączonej do zewnętrznej bazy danych i dostępnej przez internetowy interfejs API. W poniższym przykładzie pokazano, jak używać magazynu lokalnego przeglądarki.

Microsoft.Extensions.Localization Dodaj pakiet do aplikacji.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

BlazorWebAssemblyLoadAllGlobalizationData Ustaw właściwość na true w pliku projektu:

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

Kultura aplikacji do renderowania po stronie klienta jest ustawiana przy użyciu interfejsu Blazor API platformy. Wybór kultury użytkownika można utrwalić w magazynie lokalnym przeglądarki.

Podaj JS funkcje po Blazortagu <script> , aby pobrać i ustawić wybór kultury użytkownika przy użyciu magazynu lokalnego przeglądarki:

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

Uwaga

Powyższy przykład zanieczyszcza klienta za pomocą funkcji globalnych. Aby uzyskać lepsze podejście do aplikacji produkcyjnych, zobacz izolację języka JavaScript w modułach JavaScript.

Dodaj przestrzenie nazw dla System.Globalization elementu i Microsoft.JSInterop na początku Program pliku:

using System.Globalization;
using Microsoft.JSInterop;

Usuń następujący wiersz:

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

Zastąp poprzedni wiersz następującym kodem. Kod dodaje Blazorusługę lokalizacji do kolekcji usług aplikacji i AddLocalization używa JS międzyoperajności w celu wywołania JS i pobrania wyboru kultury użytkownika z magazynu lokalnego. Jeśli magazyn lokalny nie zawiera kultury dla użytkownika, kod ustawia wartość domyślną Stany Zjednoczone english (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

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

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

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

await host.RunAsync();

Uwaga

Blazor WebAssembly Obecnie aplikacje ładują tylko zasoby na podstawie elementu DefaultThreadCurrentCulture. Aby uzyskać więcej informacji, zobacz Blazor WASM opiera się tylko na bieżącej kulturze (bieżąca kultura interfejsu użytkownika nie jest szanowana) (dotnet/aspnetcore #56824).

CultureSelector Poniższy składnik pokazuje, jak wykonać następujące akcje:

  • Ustaw wybór kultury użytkownika w magazynie lokalnym przeglądarki za pośrednictwem JS międzyoperacyjnego.
  • Załaduj ponownie żądany składnik (forceLoad: true), który używa zaktualizowanej kultury.

CultureSelector.razor:

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

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

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

    private CultureInfo? selectedCulture;

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

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

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

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

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

    private CultureInfo? selectedCulture;

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

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

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

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

Wewnątrz tagu </main> zamykającego elementu w składniku MainLayout (MainLayout.razor) dodaj CultureSelector składnik:

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

Użyj składnika pokazanego CultureExample1 w sekcji Składnik demonstracyjny, aby zbadać, jak działa powyższy przykład.

Dynamiczne ustawianie kultury po stronie serwera według preferencji użytkownika

Przykłady lokalizacji, w których aplikacja może przechowywać preferencje użytkownika w magazynie lokalnym przeglądarki (typowe dla scenariuszy po stronie klienta), w lokalizacji cookie lub bazie danych (typowe dla scenariuszy po stronie serwera) lub w zewnętrznej usłudze dołączonej do zewnętrznej bazy danych i dostępnej przez internetowy interfejs API. W poniższym przykładzie pokazano, jak używać lokalizacji cookie.

Uwaga

W poniższym przykładzie przyjęto założenie, że aplikacja przyjmuje globalną interakcyjność, określając interakcyjne renderowanie po stronie serwera (interakcyjne SSR) w Routes składniku App (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Jeśli aplikacja przyjmuje interakcyjność poszczególnych stron/składników , zobacz uwagi na końcu tej sekcji, aby zmodyfikować tryby renderowania składników przykładu.

Microsoft.Extensions.Localization Dodaj pakiet do aplikacji.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Aplikacje po stronie serwera są zlokalizowane przy użyciu oprogramowania pośredniczącego lokalizacji. Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.

W pliku Program:

builder.Services.AddLocalization();

Ustaw domyślne i obsługiwane kultury aplikacji za pomocą polecenia RequestLocalizationOptions.

Przed wywołaniem metody MapRazorComponents w potoku przetwarzania żądań umieść następujący kod:

Po dodaniu oprogramowania pośredniczącego routingu (UseRouting) do potoku przetwarzania żądań umieść następujący kod:

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

app.UseRequestLocalization(localizationOptions);

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego, zobacz ASP.NET Core Middleware.

W poniższym przykładzie pokazano, jak ustawić bieżącą kulturę w obiekcie cookie , która może być odczytywana przez oprogramowanie pośredniczące lokalizacji.

Następujące przestrzenie nazw są wymagane dla App składnika:

Dodaj następujące elementy na początku App pliku składnika (Components/App.razor):

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

Dodaj następujący @code blok w dolnej części App pliku składnika:

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

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

Modyfikacje Pages/_Host.cshtml pliku wymagają następujących przestrzeni nazw:

Dodaj następującą zawartość do pliku:

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

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego, zobacz ASP.NET Core Middleware.

Jeśli aplikacja nie jest skonfigurowana do przetwarzania akcji kontrolera:

  • Dodaj usługi MVC, wywołując AddControllers kolekcję usług w Program pliku:

    builder.Services.AddControllers();
    
  • Dodaj routing punktu końcowego Program kontrolera w pliku, wywołując MapControllers polecenie IEndpointRouteBuilder (app):

    app.MapControllers();
    

Aby zapewnić interfejs użytkownika, aby umożliwić użytkownikowi wybranie kultury, użyj podejścia opartego na przekierowaniach z lokalizacją cookie. Aplikacja utrwala wybraną kulturę użytkownika za pośrednictwem przekierowania do kontrolera. Kontroler ustawia wybraną kulturę użytkownika na element cookie i przekierowuje użytkownika z powrotem do oryginalnego identyfikatora URI. Proces jest podobny do tego, co dzieje się w aplikacji internetowej, gdy użytkownik próbuje uzyskać dostęp do bezpiecznego zasobu, w którym użytkownik jest przekierowywany do strony logowania, a następnie przekierowywany z powrotem do oryginalnego zasobu.

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);
    }
}

Ostrzeżenie

LocalRedirect Użyj wyniku akcji, jak pokazano w poprzednim przykładzie, aby zapobiec otwartym atakom przekierowania. Aby uzyskać więcej informacji, zobacz Zapobieganie otwartym atakom przekierowania w programie ASP.NET Core.

Poniższy CultureSelector składnik pokazuje, jak wywołać metodę Set CultureController obiektu za pomocą nowej kultury. Składnik jest umieszczany w folderze Shared do użycia w całej aplikacji.

CultureSelector.razor:

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

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

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

    private CultureInfo? selectedCulture;

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

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

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

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

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

    private CultureInfo? selectedCulture;

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

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

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

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

CultureSelector Dodaj składnik do MainLayout składnika. Umieść następujący znacznik wewnątrz tagu zamykającego </main> w Components/Layout/MainLayout.razor pliku:

CultureSelector Dodaj składnik do MainLayout składnika. Umieść następujący znacznik wewnątrz tagu zamykającego </main> w Shared/MainLayout.razor pliku:

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

Użyj składnika pokazanego CultureExample1 w sekcji Składnik demonstracyjny, aby zbadać, jak działa powyższy przykład.

W poprzednim przykładzie przyjęto założenie, że aplikacja przyjmuje globalną interakcyjność, określając tryb renderowania interakcyjnego Routes serwera na składniku App (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Jeśli aplikacja przyjmuje interakcyjność poszczególnych stron/składników , wprowadź następujące zmiany:

  • Dodaj tryb renderowania interaktywnego CultureExample1 serwera na początku pliku składnika (Components/Pages/CultureExample1.razor):

    @rendermode InteractiveServer
    
  • W głównym układzie aplikacji (Components/Layout/MainLayout.razor) zastosuj tryb renderowania serwera interaktywnego CultureSelector do składnika:

    <CultureSelector @rendermode="InteractiveServer" />
    

Dynamiczne ustawianie kultury w obiekcie Blazor Web App według preferencji użytkownika

Ta sekcja dotyczy Blazor Web Appelementów, które przyjmują interakcyjność automatycznego (serwera i zestawu WebAssembly).

Przykłady lokalizacji, w których aplikacja może przechowywać preferencje użytkownika w magazynie lokalnym przeglądarki (typowe dla scenariuszy po stronie klienta), w lokalizacji cookie lub bazie danych (typowe dla scenariuszy po stronie serwera), zarówno magazynu lokalnego, jak i lokalizacji cookie (Blazor Web Apps z serwerem i składnikami zestawu WebAssembly) lub w usłudze zewnętrznej dołączonej do zewnętrznej bazy danych i dostępie przez internetowy interfejs API. W poniższym przykładzie pokazano, jak używać magazynu lokalnego przeglądarki dla składników renderowanych po stronie klienta (CSR) i lokalizacji cookie składników renderowanych po stronie serwera (SSR).

.Client Aktualizacje projektu

Microsoft.Extensions.Localization Dodaj pakiet do .Client projektu.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

BlazorWebAssemblyLoadAllGlobalizationData Ustaw właściwość na true w .Client pliku projektu:

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

Dodaj przestrzenie nazw dla System.Globalization elementu i Microsoft.JSInterop na początku .Client pliku projektu Program :

using System.Globalization;
using Microsoft.JSInterop;

Usuń następujący wiersz:

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

Zastąp poprzedni wiersz następującym kodem. Kod dodaje Blazorusługę lokalizacji do kolekcji usług aplikacji i AddLocalization używa JS międzyoperajności w celu wywołania JS i pobrania wyboru kultury użytkownika z magazynu lokalnego. Jeśli magazyn lokalny nie zawiera kultury dla użytkownika, kod ustawia wartość domyślną Stany Zjednoczone english (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

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

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

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

await host.RunAsync();

Uwaga

Blazor WebAssembly Obecnie aplikacje ładują tylko zasoby na podstawie elementu DefaultThreadCurrentCulture. Aby uzyskać więcej informacji, zobacz Blazor WASM opiera się tylko na bieżącej kulturze (bieżąca kultura interfejsu użytkownika nie jest szanowana) (dotnet/aspnetcore #56824).

Dodaj następujący CultureSelector składnik do .Client projektu.

Składnik przyjmuje następujące podejścia do pracy dla składników SSR lub CSR:

  • Nazwa wyświetlana każdej dostępnej kultury na liście rozwijanej jest dostarczana przez słownik, ponieważ dane globalizacji po stronie klienta zawierają zlokalizowany tekst nazw wyświetlanych kultury udostępnianych przez dane globalizacji po stronie serwera. Na przykład lokalizacja po stronie serwera jest wyświetlana English (United States) , gdy en-US jest kultura i Ingles () kiedy jest używana inna kultura. Ponieważ lokalizacja nazw wyświetlanych kultury nie jest dostępna w Blazor WebAssembly przypadku globalizacji, nazwa wyświetlana Stany Zjednoczone angielski na kliencie dla każdej załadowanej kultury to tylko en-US. Użycie słownika niestandardowego umożliwia składnikowi wyświetlanie co najmniej pełnych nazw kultury angielskiej.
  • Gdy użytkownik zmienia kulturę, JS międzyoperajności ustawia kulturę w lokalnym magazynie przeglądarki, a akcja kontrolera aktualizuje lokalizację cookie z kulturą. Kontroler zostanie dodany do aplikacji w dalszej części sekcji Aktualizacje projektu serwera.

Pages/CultureSelector.razor:

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

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

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

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

    private CultureInfo? selectedCulture;

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

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

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

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

W projekcie .Client umieść następujący CultureClient składnik, aby zbadać, jak działa globalizacja dla składników CSR.

Pages/CultureClient.razor:

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

<PageTitle>Culture Client</PageTitle>

<h1>Culture Client</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

Aktualizacje projektu serwera

Microsoft.Extensions.Localization Dodaj pakiet do projektu serwera.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Aplikacje po stronie serwera są zlokalizowane przy użyciu oprogramowania pośredniczącego lokalizacji. Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.

W pliku projektu Program serwera, w którym są zarejestrowane usługi:

builder.Services.AddLocalization();

Ustaw domyślne i obsługiwane kultury aplikacji za pomocą polecenia RequestLocalizationOptions.

Przed wywołaniem metody MapRazorComponents w potoku przetwarzania żądań umieść następujący kod:

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

app.UseRequestLocalization(localizationOptions);

W poniższym przykładzie pokazano, jak ustawić bieżącą kulturę w obiekcie cookie , która może być odczytywana przez oprogramowanie pośredniczące lokalizacji.

Następujące przestrzenie nazw są wymagane dla App składnika:

Dodaj następujące elementy na początku App pliku składnika (Components/App.razor):

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

Kultura aplikacji do renderowania po stronie klienta jest ustawiana przy użyciu interfejsu Blazor API platformy. Wybór kultury użytkownika można utrwalić w lokalnym magazynie przeglądarki dla składników CSR.

Po tagu Blazor"s<script>" podaj JS funkcje, aby uzyskać i ustawić wybór kultury użytkownika przy użyciu magazynu lokalnego przeglądarki:

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

Uwaga

Powyższy przykład zanieczyszcza klienta za pomocą funkcji globalnych. Aby uzyskać lepsze podejście do aplikacji produkcyjnych, zobacz izolację języka JavaScript w modułach JavaScript.

Dodaj następujący @code blok w dolnej części App pliku składnika:

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

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

Jeśli projekt serwera nie jest skonfigurowany do przetwarzania akcji kontrolera:

  • Dodaj usługi MVC, wywołując AddControllers kolekcję usług w Program pliku:

    builder.Services.AddControllers();
    
  • Dodaj routing punktu końcowego Program kontrolera w pliku, wywołując MapControllers polecenie IEndpointRouteBuilder (app):

    app.MapControllers();
    

Aby umożliwić użytkownikowi wybranie kultury składników SSR, użyj podejścia opartego na przekierowaniach z lokalizacją cookie. Aplikacja utrwala wybraną kulturę użytkownika za pośrednictwem przekierowania do kontrolera. Kontroler ustawia wybraną kulturę użytkownika na element cookie i przekierowuje użytkownika z powrotem do oryginalnego identyfikatora URI. Proces jest podobny do tego, co dzieje się w aplikacji internetowej, gdy użytkownik próbuje uzyskać dostęp do bezpiecznego zasobu, w którym użytkownik jest przekierowywany do strony logowania, a następnie przekierowywany z powrotem do oryginalnego zasobu.

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);
    }
}

Ostrzeżenie

LocalRedirect Użyj wyniku akcji, jak pokazano w poprzednim przykładzie, aby zapobiec otwartym atakom przekierowania. Aby uzyskać więcej informacji, zobacz Zapobieganie otwartym atakom przekierowania w programie ASP.NET Core.

CultureSelector Dodaj składnik do MainLayout składnika. Umieść następujący znacznik wewnątrz tagu zamykającego </main> w Components/Layout/MainLayout.razor pliku:

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

Użyj składnika pokazanego CultureExample1 w sekcji Składnik demonstracyjny, aby zbadać, jak działa powyższy przykład.

W projekcie serwera umieść następujący CultureServer składnik, aby zbadać, jak działa globalizacja dla składników SSR.

Components/Pages/CultureServer.razor:

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

<PageTitle>Culture Server</PageTitle>

<h1>Culture Server</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

Dodaj składniki CultureClient i CultureServer do nawigacji paska bocznego w pliku Components/Layout/NavMenu.razor:

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

Interakcyjne składniki automatyczne

Wskazówki zawarte w tej sekcji dotyczą również składników, które przyjmują tryb renderowania interakcyjnego automatycznego:

@rendermode InteractiveAuto

Lokalizacja

Jeśli aplikacja nie obsługuje jeszcze dynamicznego wyboru kultury, dodaj Microsoft.Extensions.Localization pakiet do aplikacji.

Uwaga

Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.

Lokalizacja po stronie klienta

BlazorWebAssemblyLoadAllGlobalizationData Ustaw właściwość na true w pliku projektu aplikacji (.csproj):

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

Program W pliku dodaj przestrzeń nazw dla obszaru System.Globalization nazw na początku pliku:

using System.Globalization;

Dodaj Blazorusługę lokalizacji do kolekcji usług aplikacji za pomocą polecenia AddLocalization:

builder.Services.AddLocalization();

Lokalizacja po stronie serwera

Użyj oprogramowania pośredniczącego lokalizacji, aby ustawić kulturę aplikacji.

Jeśli aplikacja nie obsługuje jeszcze dynamicznego wyboru kultury:

  • Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.
  • Określ domyślne i obsługiwane kultury aplikacji w Program pliku. W poniższym przykładzie są konfigurowane obsługiwane kultury dla języka Stany Zjednoczone angielskiego i kostarykańskiej języka hiszpańskiego.
builder.Services.AddLocalization();

Umieść oprogramowanie pośredniczące żądań lokalizacji przed dowolnym oprogramowaniem pośredniczącym, które może sprawdzać kulturę żądań. Ogólnie rzecz biorąc, umieść oprogramowanie pośredniczące bezpośrednio przed wywołaniem polecenia MapRazorComponents:

Natychmiast po dodaniu oprogramowania pośredniczącego routingu (UseRouting) do potoku przetwarzania:

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

app.UseRequestLocalization(localizationOptions);

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego, zobacz ASP.NET Core Middleware.

  • Dodaj usługi lokalizacji do aplikacji za pomocą polecenia AddLocalization.
  • Określ domyślne i obsługiwane kultury aplikacji w programie Startup.Configure (Startup.cs). W poniższym przykładzie są konfigurowane obsługiwane kultury dla języka Stany Zjednoczone angielskiego i kostarykańskiej języka hiszpańskiego.

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

Natychmiast Startup.Configure po dodaniu oprogramowania pośredniczącego routingu (UseRouting) do potoku przetwarzania:

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

app.UseRequestLocalization(localizationOptions);

Aby uzyskać informacje na temat zamawiania oprogramowania pośredniczącego lokalizacji w potoku oprogramowania pośredniczącego Startup.Configureprogramu , zobacz ASP.NET Core Middleware.

Jeśli aplikacja powinna lokalizować zasoby na podstawie ustawienia kultury użytkownika, użyj kultury cookielokalizacji . Użycie elementu cookie zapewnia, że połączenie protokołu WebSocket może poprawnie propagować kulturę. Jeśli schematy lokalizacji są oparte na ścieżce adresu URL lub ciągu zapytania, schemat może nie być w stanie pracować z zestawami WebSocket, dlatego nie można utrwały kultury. W związku z tym zalecaną metodą jest użycie kultury cookielokalizacji . Zobacz sekcję Dynamiczne ustawianie kultury po stronie serwera według preferencji użytkownika w tym artykule, aby wyświetlić przykładowe Razor wyrażenie, które utrwala wybór kultury użytkownika.

Przykład zlokalizowanych zasobów

Przykład zlokalizowanych zasobów w tej sekcji działa z poprzednimi przykładami w tym artykule, w których obsługiwane przez aplikację kultury to angielski (en) jako domyślne ustawienia regionalne i hiszpańskie (es) jako ustawienia regionalne możliwe do wybrania przez użytkownika lub określone w przeglądarce alternatywne ustawienia regionalne.

Utwórz plik zasobów dla każdego ustawienia regionalnego. W poniższym przykładzie zasoby są tworzone dla Greeting ciągu w języku angielskim i hiszpańskim:

  • Angielski (en): Hello, World!
  • Hiszpański (es): ¡Hola, Mundo!

Uwaga

Poniższy plik zasobu można dodać w programie Visual Studio, klikając prawym przyciskiem myszy Pages folder i wybierając polecenie Dodaj>nowy plik zasobów elementów.> Nazwij plik CultureExample2.resx. Po wyświetleniu edytora podaj dane dla nowego wpisu. Ustaw wartość Name na Greeting i Wartość na Hello, World!. Zapisz plik.

W przypadku korzystania z programu Visual Studio Code zalecamy zainstalowanie przeglądarki i edytora ResX Tima Heuera. Dodaj pusty CultureExample2.resx plik do Pages folderu. Rozszerzenie automatycznie przejmuje zarządzanie plikiem w interfejsie użytkownika. Wybierz przycisk Dodaj nowy zasób. Postępuj zgodnie z instrukcjami, aby dodać wpis ( Greeting klucz), Hello, World! (wartość) i None (komentarz). Zapisz plik. Jeśli zamkniesz i ponownie otworzysz plik, zobaczysz Greeting zasób.

Firma Tim Heuer's ResX Viewer and Editor nie jest własnością ani nie jest utrzymywana przez firmę Microsoft i nie jest objęta żadną umową pomoc techniczna firmy Microsoft ani licencją.

Poniżej przedstawiono typowy plik zasobów. Możesz ręcznie umieścić pliki zasobów w folderze aplikacji Pages , jeśli nie chcesz używać wbudowanych narzędzi ze zintegrowanym środowiskiem projektowym (IDE), takim jak wbudowany edytor plików zasobów programu Visual Studio lub program Visual Studio Code z rozszerzeniem do tworzenia i edytowania plików zasobów.

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>

Uwaga

Poniższy plik zasobu można dodać w programie Visual Studio, klikając prawym przyciskiem myszy Pages folder i wybierając polecenie Dodaj>nowy plik zasobów elementów.> Nazwij plik CultureExample2.es.resx. Po wyświetleniu edytora podaj dane dla nowego wpisu. Ustaw wartość Name na Greeting i Wartość na ¡Hola, Mundo!. Zapisz plik.

W przypadku korzystania z programu Visual Studio Code zalecamy zainstalowanie przeglądarki i edytora ResX Tima Heuera. Dodaj pusty CultureExample2.resx plik do Pages folderu. Rozszerzenie automatycznie przejmuje zarządzanie plikiem w interfejsie użytkownika. Wybierz przycisk Dodaj nowy zasób. Postępuj zgodnie z instrukcjami, aby dodać wpis ( Greeting klucz), ¡Hola, Mundo! (wartość) i None (komentarz). Zapisz plik. Jeśli zamkniesz i ponownie otworzysz plik, zobaczysz Greeting zasób.

Poniżej przedstawiono typowy plik zasobów. Możesz ręcznie umieścić pliki zasobów w folderze aplikacji Pages , jeśli nie chcesz używać wbudowanych narzędzi ze zintegrowanym środowiskiem projektowym (IDE), takim jak wbudowany edytor plików zasobów programu Visual Studio lub program Visual Studio Code z rozszerzeniem do tworzenia i edytowania plików zasobów.

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>

Poniższy składnik demonstruje użycie zlokalizowanego Greeting ciągu za pomocą IStringLocalizer<T>polecenia . Znaczniki Razor @Loc["Greeting"] w poniższym przykładzie lokalizuje ciąg kluczem do Greeting wartości, która jest ustawiana w poprzednich plikach zasobów.

Dodaj przestrzeń nazw do Microsoft.Extensions.Localization pliku aplikacji _Imports.razor :

@using Microsoft.Extensions.Localization

CultureExample2.razor:

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

<h1>Culture Example 2</h1>

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

<h2>Greeting</h2>

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

<p>
    @greeting
</p>

@code {
    private string? greeting;

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

Opcjonalnie dodaj element menu składnika CultureExample2 do nawigacji w składniku NavMenu (NavMenu.razor).

Źródło referencyjne dostawcy kultury zestawu WebAssembly

Aby dokładniej zrozumieć, jak platforma Blazor przetwarza lokalizację, zobacz klasę WebAssemblyCultureProvider w źródle referencyjnym ASP.NET Core.

Uwaga

Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Współdzielone zasoby

Aby utworzyć udostępnione zasoby lokalizacji, zastosuj następujące podejście.

  • Utwórz fikcyjną klasę z dowolną nazwą klasy. W poniższym przykładzie:

    • Aplikacja używa BlazorSample przestrzeni nazw, a zasoby lokalizacji używają BlazorSample.Localization przestrzeni nazw.
    • Fikcyjna klasa nosi nazwę SharedResource.
    • Plik klasy jest umieszczany w Localization folderze głównym aplikacji.

    Localization/SharedResource.cs:

    namespace BlazorSample.Localization;
    
    public class SharedResource
    {
    }
    
  • Utwórz pliki zasobów udostępnionych za pomocą akcji kompilacji .Embedded resource W poniższym przykładzie:

    • Pliki są umieszczane w folderze Localization z fikcyjną SharedResource klasą (Localization/SharedResource.cs).

    • Nadaj plikom zasobów nazwę zgodną z nazwą fikcyjnej klasy. Poniższe przykładowe pliki zawierają domyślny plik lokalizacji i plik lokalizacji hiszpańskiej (es).

    • Localization/SharedResource.resx

    • Localization/SharedResource.es.resx

    Ostrzeżenie

    W przypadku zastosowania podejścia w tej sekcji nie można jednocześnie ustawić LocalizationOptions.ResourcesPath zasobów i użyć ich IStringLocalizerFactory.Create do załadowania zasobów.

  • Aby odwołać się do fikcyjnej klasy wprowadzonej IStringLocalizer<T> w składniku Razor , umieść dyrektywę @using dla przestrzeni nazw lokalizacji lub uwzględnij przestrzeń nazw lokalizacji w fikcyjnym odwołaniu do klasy. W następujących przykładach:

    • Pierwszy przykład zawiera Localization przestrzeń nazw fikcyjnej SharedResource klasy z dyrektywą @using .
    • Drugi przykład jawnie określa SharedResource przestrzeń nazw fikcyjnej klasy.

    W składniku Razor użyj jednej z następujących metod:

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

Aby uzyskać dodatkowe wskazówki, zobacz Globalizacja i lokalizacja w programie ASP.NET Core.

Zastępowanie lokalizacji przy użyciu okienka "Czujniki" w narzędziach deweloperskich

W przypadku używania przesłonięć lokalizacji przy użyciu okienka Czujniki w narzędziach deweloperskich Google Chrome lub Microsoft Edge język rezerwowy jest resetowany po wstępnieenderingu. Unikaj ustawiania języka przy użyciu okienka Czujniki podczas testowania. Ustaw język przy użyciu ustawień języka przeglądarki.

Aby uzyskać więcej informacji, zobacz Blazor Lokalizacja nie działa z InteractiveServer (dotnet/aspnetcore #53707).

Dodatkowe zasoby