Globalisierung und Lokalisierung in ASP.NET Core Blazor

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

In diesem Artikel wird erläutert, wie Sie globalisierte und lokalisierte Inhalte für Benutzer*innen in verschiedenen Kulturen und Sprachen rendern.

Globalisierung und Lokalisierung

Für die Globalisierung ermöglicht Blazor eine Formatierung von Zahlen und Datumsangaben. Für die Lokalisierung rendert Blazor Inhalte unter Verwendung des .NET-Ressourcensystems.

Lokalisierungsfeatures von ASP.NET Core werden eingeschränkt unterstützt:

Unterstützt:IStringLocalizer und IStringLocalizer<T> werden in Blazor-Apps unterstützt.

Nicht unterstützt:IHtmlLocalizer, IViewLocalizer und die Lokalisierung von Datenanmerkungen sind ASP.NET Core MVC-Features und werden in Blazor-Apps nicht unterstützt.

In diesem Artikel wird beschrieben, wie die Globalisierungs- und Lokalisierungsfeatures von Blazor basierend auf folgenden Angaben verwendet werden:

  • Accept-Language-Header, der vom Browser basierend auf den Spracheinstellungen eines Benutzers in den Browsereinstellungen festgelegt wird.
  • Eine von der App festgelegte Kultur, die nicht auf dem Wert des Accept-Language-Headers basiert. Die Einstellung kann für alle Benutzer statisch oder abhängig von der App-Logik dynamisch sein. Wenn die Einstellung auf der Voreinstellung des Benutzers basiert, wird die Einstellung in der Regel gespeichert und bei zukünftigen Besuchen erneut geladen.

Allgemeine Informationen finden Sie unter den folgenden Ressourcen:

Häufig werden die Begriffe Sprache und Kultur synonym verwendet, wenn es um Globalisierungs- und Lokalisierungskonzepte geht.

In diesem Artikel bezieht sich die Sprache auf die Auswahl, die von einem Benutzer in den Einstellungen des Browsers getroffen wurde. Die Sprachauswahl des Benutzers wird in Browseranforderungen im Accept-Language-Header übermittelt. Browsereinstellungen verwenden in der Regel das Wort „Sprache“ in der Benutzeroberfläche.

Kultur bezieht sich auf Member von .NET und der Blazor-API. Die Anforderung eines Benutzers kann z. B. den Accept-Language-Header enthalten, der eine Sprache aus Sicht des Benutzers angibt. Letztendlich legt aber die App die CurrentCulture-Eigenschaft („culture“) anhand der Sprache fest, die der Benutzer angefordert hat. Die API verwendet in der Regel das Wort „culture“ im Namen ihrer Member.

Hinweis

Die Codebeispiele in diesem Artikel verwenden Nullwerte zulassende Verweistypen (Nullable Reference Types, NRTs) und die statische Analyse des NULL-Zustands des .NET-Compilers, die in ASP.NET Core in .NET 6 oder höher unterstützt werden. Entfernen Sie bei ASP.NET Core 5.0 oder früher die NULL-Typbezeichnung (?) aus den Beispielen des Artikels.

Globalisierung

Die Attributanweisung @bind wendet Formate an und analysiert Werte für die Anzeige basierend auf der ersten bevorzugten Sprache des*der Benutzer*in, die die App unterstützt. @bind unterstützt den @bind:culture-Parameter, um eine System.Globalization.CultureInfo-Klasse zum Analysieren und Formatieren eines Werts.

Der Zugriff auf die aktuelle Kultur kann über die System.Globalization.CultureInfo.CurrentCulture-Eigenschaft erfolgen.

CultureInfo.InvariantCulture wird für die folgenden Feldtypen verwendet (<input type="{TYPE}" />, wobei der Platzhalter {TYPE} der Typ ist):

  • date
  • number

Diese Feldtypen:

  • werden basierend auf ihren entsprechenden browserbasierten Formatierungsregeln angezeigt.
  • können keinen Freiformtext enthalten.
  • bieten Benutzerinteraktionsmerkmale basierend auf der Implementierung des Browsers.

Bei Verwendung der Feldtypen date und number wird die Angabe einer Kultur mit @bind:culture nicht empfohlen, da Blazor integrierte Unterstützung für das Rendern von Werten in der aktuellen Kultur bietet.

Die folgenden Feldtypen verfügen über spezifische Formatierungsanforderungen und werden derzeit nicht von Blazor unterstützt, weil sie von keinem der wichtigsten Browser unterstützt werden:

  • datetime-local
  • month
  • week

Informationen zur aktuellen Browserunterstützung der vorangehenden Typen finden Sie unter Can I use.

Unterstützung der .NET-Globalisierung und internationaler Komponenten für Unicode (Blazor WebAssembly)

Blazor WebAssembly verwendet eine API mit reduzierter Globalisierung und eine Reihe integrierter ICU-Gebietsschemas (International Components for Unicode). Weitere Informationen finden Sie unter .NET-Globalisierung und ICU: ICU auf WebAssembly.

Informationen zum Laden einer benutzerdefinierten ICU-Datendatei zum Steuern der Gebietsschemas der App finden Sie unter WASM Globalization Icu (WASM-Globalisierung ICU). Derzeit ist das manuelle Erstellen der benutzerdefinierten ICU-Datendatei erforderlich. .NET-Tools zur Vereinfachung des Erstellungsprozesses der Datei sind für .NET 9 im November 2024 geplant.

Blazor WebAssembly verwendet eine API mit reduzierter Globalisierung und eine Reihe integrierter ICU-Gebietsschemas (International Components for Unicode). Weitere Informationen finden Sie unter .NET-Globalisierung und ICU: ICU auf WebAssembly.

Das Laden einer benutzerdefinierten Teilmenge von Gebietsschemas in einer Blazor WebAssembly-App wird in .NET 8 oder höher unterstützt. Weitere Informationen erhalten Sie in diesem Abschnitt für eine Version 8.0 oder höher dieses Artikels.

Invariante Globalisierung

Wenn für die App keine Lokalisierung erforderlich ist, konfigurieren Sie die App so, dass die invariante Kultur unterstützt wird, die in der Regel auf US-Englisch (en-US) basiert. Legen Sie die InvariantGlobalization-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Alternativ können Sie die invariante Globalisierung mit folgenden Ansätzen konfigurieren:

  • In runtimeconfig.json:

    {
      "runtimeOptions": {
        "configProperties": {
          "System.Globalization.Invariant": true
        }
      }
    }
    
  • Mit einer Umgebungsvariable:

    • Schlüssel: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
    • Wert: true oder 1

Weitere Informationen finden Sie unter Laufzeitkonfigurationsoptionen für Globalisierung (.NET-Dokumentation).

Demokomponente

Die folgende CultureExample1-Komponente kann verwendet werden, um die Globalisierungs- und Lokalisierungskonzepte von Blazor zu veranschaulichen, die in diesem Artikel behandelt werden.

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

Das Zahlenzeichenfolgenformat (N2) im obigen Beispiel (.ToString("N2")) ist ein standardmäßiger numerischer .NET-Formatbezeichner. Das N2-Format wird für alle numerischen Typen unterstützt, enthält ein Gruppentrennzeichen und rendert bis zu zwei Dezimalstellen.

Fügen Sie der Navigation in der NavMenu-Komponente (NavMenu.razor) für die CultureExample1-Komponente optional ein Menüelement hinzu.

Dynamisches Festlegen der Kultur über den Accept-Language-Header

Fügen Sie der App das Paket Microsoft.Extensions.Localization hinzu.

Der Accept-Language-Header wird vom Browser festgelegt und durch die Spracheinstellungen des Benutzers in den Browsereinstellungen gesteuert. In den Browsereinstellungen legt ein Benutzer eine oder mehrere bevorzugte Sprachen in der gewünschten Reihenfolge fest. Die Reihenfolge der Einstellung wird vom Browser verwendet, um Qualitätswerte (q, 0-1) für die einzelnen Sprachen im Header festzulegen. Im folgenden Beispiel wird US-Englisch, Englisch und Costa Rica-Spanisch mit Bevorzugung von US-Englisch oder Englisch angegeben:

Sprache akzeptieren: en-US,en;q=0.9,es-CR;q=0.8

Die Kultur der App wird durch Abgleich der ersten angeforderten Sprache festgelegt, die mit einer unterstützten Kultur der App übereinstimmt.

Legen Sie bei clientseitiger Entwicklung die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der clientseitigen App (.csproj) auf true fest:

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

Bei clientseitiger Entwicklung wird das dynamische Festlegen der Kultur aus dem Header Accept-Language nicht unterstützt.

Hinweis

Wenn die Spezifikation der App eine Beschränkung der unterstützten Kulturen auf eine explizite Liste erfordert, lesen Sie den Abschnitt Dynamisches Festlegen der clientseitigen Kultur durch Benutzereinstellung in diesem Artikel.

Apps werden mit Lokalisierungsmiddleware lokalisiert. Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.

Fügen Sie in der Datei Program die folgende Zeile hinzu, in der Dienste registriert sind:

builder.Services.AddLocalization();

In serverseitige Entwicklung können Sie die unterstützten Kulturen der App unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline angeben. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und Costa Rica-Spanisch konfiguriert:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline der Program-Datei finden Sie unter ASP.NET Core-Middleware.

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um die Funktionsweise der Globalisierung zu untersuchen. Erstellen Sie eine Anforderung mit US-Englisch (en-US). Wechseln Sie in den Spracheinstellungen des Browsers zu Costa Rica-Spanisch (es-CR). Fordern Sie die Webseite erneut an.

Hinweis

In einigen Browsern müssen Sie die Standardspracheinstellung sowohl für Anforderungen als auch für die Benutzeroberflächeneinstellungen des Browsers verwenden. Dies kann das Ändern der Sprache in eine Sprache, die Sie verstehen, erschweren, da alle Einstellungsbildschirme der Benutzeroberfläche möglicherweise zu einer Sprache führen, die Sie nicht lesen können. Ein Browser wie Opera ist eine gute Wahl für Tests, da Sie damit eine Standardsprache für Webseitenanforderungen festlegen können, die Einstellungen für die Benutzeroberfläche des Browsers aber in Ihrer Sprache bleiben.

Wenn die Kultur US-Englisch (en-US) ist, verwendet die gerenderte Komponente die Monat/Tag-Datumsformatierung (6/7), 12-Stunden-Zeitangaben (AM/PM) und Kommatrennzeichen in Zahlen mit einem Punkt für den Dezimalwert (1,999.69):

  • Datum: 6/7/2021 6:45:22 AM
  • Zahl: 1,999.69

Wenn als Kultur Costa Rica-Spanisch (es-CR) verwendet wird, verwendet die gerenderte Komponente die Tag/Monat-Datumsformatierung (7/6), 24-Stunden-Zeitangaben und Punkttrennzeichen in Zahlen mit einem Komma für den Dezimalwert (1.999,69):

  • Datum: 7/6/2021 6:49:38
  • Zahl: 1.999,69

Statisches Festlegen der clientseitigen Kultur

Legen Sie die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Mit der IL-Linkerkonfiguration (Intermediate Language, Zwischensprache) für clientseitiges Rendering (CSR) werden mit Ausnahme von explizit angeforderten Gebietsschemata alle Internationalisierungsinformationen standardmäßig entfernt. Weitere Informationen finden Sie unter Konfigurieren des Linkers für Blazor in ASP.NET Core.

Die Kultur der App kann in JavaScript festgelegt werden, wenn Blazor mit der Blazor-Startoption applicationCulture gestartet wird. Im folgenden Beispiel wird die App so konfiguriert, dass sie mit der Kultur US-Englisch (en-US) gestartet wird.

Verhindern Sie Blazor Autostart, indem Sie autostart="false" den Blazor<script>-Tag hinzufügen:

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

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Fügen Sie den folgenden <script>-Block hinter dem Blazor<script>-Tag und vor dem Abschluss den </body>-Tag hinzu:

Blazor Web-App:

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

Blazor WebAssembly eigenständig:

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

Der Wert von applicationCulture muss dem Sprachentagformat BCP-47 entsprechen. Weitere Informationen zum Start von Blazor finden Sie unter Starten von ASP.NET Core Blazor.

Eine Alternative zum Festlegen der Startoption von Blazor für die Kultur ist das Festlegen der Kultur in C#-Code. Legen Sie CultureInfo.DefaultThreadCurrentCulture und CultureInfo.DefaultThreadCurrentUICulture in der Program-Datei auf dieselbe Kultur fest.

Fügen Sie den Namespace System.Globalization der Program-Datei hinzu:

using System.Globalization;

Fügen Sie die Kultureinstellungen vor der Zeile hinzu, die WebAssemblyHostBuilder erstellt und ausführt (await builder.Build().RunAsync();):

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

Wichtig

Legen Sie DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture stets auf dieselbe Kultur fest, um IStringLocalizer und IStringLocalizer<T> verwenden zu können.

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um die Funktionsweise der Globalisierung zu untersuchen. Erstellen Sie eine Anforderung mit US-Englisch (en-US). Wechseln Sie in den Spracheinstellungen des Browsers zu Costa Rica-Spanisch (es-CR). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache Rica-Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Statisches Festlegen der serverseitigen Kultur

Serverseitige Apps werden über Lokalisierungsmiddleware lokalisiert. Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.

Gehen Sie in der Program-Datei folgendermaßen vor:

builder.Services.AddLocalization();

Geben Sie die statische Kultur unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline in der Program-Datei an. Im folgenden Beispiel wird US-Englisch konfiguriert:

app.UseRequestLocalization("en-US");

Der Kulturwert für UseRequestLocalization muss dem Sprachentagformat BCP-47 entsprechen.

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline der Program-Datei finden Sie unter ASP.NET Core-Middleware.

Serverseitige Apps werden über Lokalisierungsmiddleware lokalisiert. Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

Geben Sie unmittelbar nach dem Hinzufügen der Routing-Middleware zur Verarbeitungspipeline die statische Kultur in Startup.Configure (Startup.cs) an. Im folgenden Beispiel wird US-Englisch konfiguriert:

app.UseRequestLocalization("en-US");

Der Kulturwert für UseRequestLocalization muss dem Sprachentagformat BCP-47 entsprechen.

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Startup.Configure finden Sie unter ASP.NET Core-Middleware.

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um die Funktionsweise der Globalisierung zu untersuchen. Erstellen Sie eine Anforderung mit US-Englisch (en-US). Wechseln Sie in den Spracheinstellungen des Browsers zu Costa Rica-Spanisch (es-CR). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache Rica-Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Dynamisches Festlegen der clientseitigen Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellungen von Benutzer*innen speichern kann, sind der lokale Speicher des Browsers (bei clientseitigen Szenarios üblich), in einem cookie oder einer Datenbank für die Lokalisierung (bei serverseitigen Szenarios üblich) oder in einem externen Dienst, der an eine externe Datenbank angefügt und über eine Web-API zugänglich ist. Im folgenden Beispiel wird die Verwendung des lokalen Speichers im Browser veranschaulicht.

Fügen Sie der App das Paket Microsoft.Extensions.Localization hinzu.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Legen Sie die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei auf true fest:

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

Die Kultur der App für clientseitiges Rendering (CSR) wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers kann im lokalen Browserspeicher gespeichert werden.

Geben Sie JS-Funktionen nach den Blazor<script> Tagsan, um die Kulturauswahl der Benutzer*innen im lokalen Browserspeicher abzurufen und festzulegen:

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

Hinweis

Das Beispiel oben verunreinigt den Client mit globalen Funktionen. Einen besseren Ansatz für Produktions-Apps finden Sie unter JavaScript-Isolation in JavaScript-Modulen.

Fügen Sie am Anfang der Program-Datei die Namespaces für System.Globalization und Microsoft.JSInterop hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile:

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

Ersetzen Sie die obige Zeile durch den folgenden Code. Der Code fügt den Lokalisierungsdienst von Blazor mit AddLocalization zur Dienstsammlung der App hinzu und verwendet JS-Interop, um JS aufzurufen und die Kulturauswahl des Benutzers aus dem lokalen Speicher abzurufen. Wenn der lokale Speicher keine Kultur für den Benutzer enthält, legt der Code US-Englisch (en-US) als Standardwert fest.

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.GetCulture(result ?? defaultCulture);

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

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

await host.RunAsync();

Wichtig

Legen Sie DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture stets auf dieselbe Kultur fest, um IStringLocalizer und IStringLocalizer<T> verwenden zu können.

Die folgende CultureSelector-Komponente zeigt, wie die folgenden Aktionen durchgeführt werden:

  • Festlegen der Kulturauswahl von Benutzer*innen über JS-Interop auf einen lokalen Browserspeicher
  • Erneutes Laden der angeforderten Komponente (forceLoad: true), die die aktualisierte Kultur verwendet

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-CR"),
    };

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

Fügen Sie im schließenden Tag des </main>-Elements in der Komponente MainLayout (MainLayout.razor) die Komponente CultureSelector hinzu:

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

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um zu untersuchen, wie das obige Beispiel funktioniert.

Dynamisches Festlegen der serverseitigen Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellungen von Benutzer*innen speichern kann, sind der lokale Speicher des Browsers (bei clientseitigen Szenarios üblich), in einem cookie oder einer Datenbank für die Lokalisierung (bei serverseitigen Szenarios üblich) oder in einem externen Dienst, der an eine externe Datenbank angefügt und über eine Web-API zugänglich ist. Das folgende Beispiel veranschaulicht, wie ein Lokalisierungs-cookie verwendet wird.

Hinweis

Im folgenden Beispiel wird davon ausgegangen, dass die Anwendung globale Interaktivität annimmt, indem das interaktive serverseitige Rendering (interaktive SSR) auf der Routes-Komponente in der App-Komponente (Components/App.razor) angegeben wird:

<Routes @rendermode="InteractiveServer" />

Wenn die App Interaktivität pro Seite/Komponente verwendet, lesen Sie die Hinweise am Ende dieses Abschnitts, um die Rendermodi der Komponenten des Beispiels zu ändern.

Fügen Sie der App das Paket Microsoft.Extensions.Localization hinzu.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Serverseitige Apps werden über Lokalisierungsmiddleware lokalisiert. Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.

Gehen Sie in der Program-Datei folgendermaßen vor:

builder.Services.AddLocalization();

Legen Sie die standardmäßigen und unterstützten Kulturen der App mit RequestLocalizationOptions fest.

Platzieren Sie vor dem Aufruf an app.MapRazorComponents in der Anforderungsverarbeitungspipeline den folgenden Code:

Platzieren Sie nach dem Aufruf an app.UseRouting in der Anforderungsverarbeitungspipeline den folgenden Code:

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline finden Sie unter ASP.NET Core-Middleware.

Im folgenden Beispiel wird veranschaulicht, wie die aktuelle Kultur in einem cookie festgelegt werden kann, das von der Lokalisierungsmiddleware gelesen werden kann.

Die folgenden Namespaces sind für die App-Komponente erforderlich:

Fügen Sie folgendes am Anfang der App-Komponentendatei (Components/App.razor) hinzu:

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

Fügen Sie den folgenden @code-Block am Ende der App-Komponentendatei hinzu:

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

Änderungen an der Pages/_Host.cshtml-Datei erfordern die folgenden Namespaces:

Fügen Sie der Datei die folgende Zeile hinzu:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline finden Sie unter ASP.NET Core-Middleware.

Befolgen Sie die folgenden Schritte, wenn die App nicht für die Verarbeitung von Controlleraktionen konfiguriert ist:

  • Fügen Sie MVC-Dienste hinzu, indem Sie AddControllers für die Dienstsammlung in der Program-Datei aufrufen:

    builder.Services.AddControllers();
    
  • Fügen Sie Controllerendpunktrouting in der Program-Datei hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen (app):

    app.MapControllers();
    

Um eine Benutzeroberfläche bereitzustellen, die Benutzern das Auswählen einer Kultur ermöglicht, wird eine umleitungsbasierte Vorgehensweise mit einem Lokalisierungs-cookie empfohlen. Die App behält die vom Benutzer ausgewählte Kultur mithilfe einer Umleitung an einen Controller bei. Der Controller legt die ausgewählte Kultur des Benutzers mit einem cookie fest und leitet den Benutzer wieder an den ursprünglichen URI weiter. Der Prozess ist ähnelt dem Ablauf in einer Web-App, wenn ein Benutzer versucht, auf eine sichere Ressource zuzugreifen: der Benutzer wird an eine Anmeldeseite umgeleitet und dann wieder zur ursprünglichen Ressource geleitet.

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

Warnung

Verwenden Sie das LocalRedirect Aktionsergebnis wie im vorherigen Beispiel gezeigt, um offene Umleitungsangriffe zu verhindern. Weitere Informationen finden Sie unter Verhindern von Open-Redirect-Angriffen in ASP.NET Core.

Die folgende CultureSelector-Komponente zeigt, wie Sie die Set-Methode von CultureController mit der neuen Kultur aufrufen. Die Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

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-CR"),
    };

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

Fügen Sie die CultureSelector-Komponente der MainLayout-Komponente hinzu. Platzieren Sie das folgende Markup innerhalb des schließenden </main>-Tags in der Components/Layout/MainLayout.razor-Datei:

Fügen Sie die CultureSelector-Komponente der MainLayout-Komponente hinzu. Platzieren Sie das folgende Markup innerhalb des schließenden </main>-Tags in der Shared/MainLayout.razor-Datei:

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

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um zu untersuchen, wie das obige Beispiel funktioniert.

Im vorherigen Beispiel wird davon ausgegangen, dass die App globale Interaktivität verwendet, indem sie den interaktiven Server-Rendermodus für die Routes-Komponente in der App-Komponente (Components/App.razor) angibt:

<Routes @rendermode="InteractiveServer" />

Wenn die App Interaktivität pro Seite/Komponente verwendet, nehmen Sie die folgenden Änderungen vor:

  • Fügen Sie den Rendermodus Interaktiver Server oben in der Komponentendatei CultureExample1 hinzu (Components/Pages/CultureExample1.razor):

    @rendermode InteractiveServer
    
  • Wenden Sie im Hauptlayout der App (Components/Layout/MainLayout.razor) den Rendermodus Interaktiver Server auf die Komponente CultureSelector an:

    <CultureSelector @rendermode="InteractiveServer" />
    

Dynamisches Festlegen der Kultur in einer Blazor Web App nach Benutzereinstellung

Dieser Abschnitt bezieht sich auf Blazor Web-Apps, die autoaktive Interaktivität (Server und WebAssembly) übernehmen.

Beispiele für Speicherorte, an denen eine App die Einstellungen von Benutzer*innen speichern kann, sind der lokale Speicher des Browsers (bei clientseitigen Szenarien üblich), in einer Lokalisierung cookie oder einer Datenbank (bei serverseitigen Szenarien üblich) sowohl lokale Speicherung als auch eine Lokalisierung cookie (BlazorWebApps mit Server- und WebAssembly-Komponenten), oder in einem externen Dienst, der an eine externe Datenbank angefügt und über eine web API zugänglich ist. Im folgenden Beispiel wird veranschaulicht, wie Sie den lokalen Browserspeicher für clientseitige gerenderte Komponenten (CSR) und eine Lokalisierung cookie für serverseitig gerenderte Komponenten (SSR) verwenden.

Aktualisierungen des .Client Projekts

Microsoft.Extensions.Localization-Paket zum .Client Projekt hinzufügen.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Legen Sie die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft auf true in der .ClientProjektdatei fest:

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

Fügen Namespaces für System.Globalization und Microsoft.JSInterop am Anfang der .Client-Projektdatei Program hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile:

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

Ersetzen Sie die obige Zeile durch den folgenden Code. Der Code fügt den Lokalisierungsdienst von Blazor mit AddLocalization zur Dienstsammlung der App hinzu und verwendet JS-Interop, um JS aufzurufen und die Kulturauswahl des Benutzers aus dem lokalen Speicher abzurufen. Wenn der lokale Speicher keine Kultur für den Benutzer enthält, legt der Code US-Englisch (en-US) als Standardwert fest.

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.GetCulture(result ?? defaultCulture);

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

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

await host.RunAsync();

Wichtig

Legen Sie DefaultThreadCurrentCulture und DefaultThreadCurrentUICulture stets auf dieselbe Kultur fest, um IStringLocalizer und IStringLocalizer<T> verwenden zu können.

Fügen Sie folgende CultureSelector Komponente dem .Client Projekt hinzu.

Die Komponente funktioniert mit den folgenden Ansätzen für SSR- oder CSR-Komponenten:

  • Der Anzeigename jeder verfügbaren Kultur in der Dropdownliste wird von einem Wörterbuch bereitgestellt, da clientseitige Globalisierungsdaten lokalisierten Text von Kulturanzeigenamen enthalten, die von serverseitigen Globalisierungsdaten bereitgestellt werden. So wird beispielsweise die serverseitige Lokalisierung English (United States) angezeigt, wenn en-US es sich um Kultur handelt und Ingles () bei Verwendung einer anderen Kultur. Da die Lokalisierung der Kulturanzeigenamen Blazor WebAssembly globalisierungsbedingt nicht verfügbar ist, ist der Anzeigename für Englisch (USA) auf dem Client für jede geladene Kultur einfach en-US. Durch die Verwendung eines Benutzerwörterbuchs kann die Komponente zumindest vollständige englische Kulturnamen anzeigen.
  • Wenn der/die Benutzer*in die Kultur ändert, JS legt Interop die Kultur im lokalen Browserspeicher fest, und eine Controlleraktion aktualisiert die Lokalisierung cookie mit der Kultur. Der Controller wird der App später im Abschnitt Server-Projektaktualisierungen hinzugefügt.

Pages/CultureSelector.razor:

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

<p>
    <label>
        Select your locale:
        <select @bind="Culture">
            @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 Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                JS.InvokeVoidAsync("blazorCulture.set", value.Name);

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

Platzieren Sie im .Client Projekt die folgende CultureClient Komponente, um zu untersuchen, wie Globalisierung für CSR-Komponenten funktioniert.

Pages/CultureClient.razor:

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

<PageTitle>Culture Client</PageTitle>

<h1>Culture Client</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;
}

Serverprojektaktualisierungen

Fügen Sie das Microsoft.Extensions.Localization Paket dem Serverprojekt hinzu.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Serverseitige Apps werden über Lokalisierungsmiddleware lokalisiert. Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.

In der Datei des Serverprojekts, Program in der Dienste registriert sind:

builder.Services.AddLocalization();

Legen Sie die standardmäßigen und unterstützten Kulturen der App mit RequestLocalizationOptions fest.

Platzieren Sie vor dem Aufruf an app.MapRazorComponents in der Anforderungsverarbeitungspipeline den folgenden Code:

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

app.UseRequestLocalization(localizationOptions);

Im folgenden Beispiel wird veranschaulicht, wie die aktuelle Kultur in einem cookie festgelegt werden kann, das von der Lokalisierungsmiddleware gelesen werden kann.

Die folgenden Namespaces sind für die App-Komponente erforderlich:

Fügen Sie folgendes am Anfang der App-Komponentendatei (Components/App.razor) hinzu:

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

Die Kultur der App für clientseitiges Rendering (CSR) wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers/einer Benutzerin kann bei CSR-Komponenten im lokalen Browserspeicher gespeichert werden.

Nach dem Blazor<script> Tag geben Sie JS Funktionen an, um die Kulturauswahl der Benutzer*innen im lokalem Browserspeicher abzurufen und festzulegen:

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

Hinweis

Das Beispiel oben verunreinigt den Client mit globalen Funktionen. Einen besseren Ansatz für Produktions-Apps finden Sie unter JavaScript-Isolation in JavaScript-Modulen.

Fügen Sie den folgenden @code-Block am Ende der App-Komponentendatei hinzu:

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

Wenn das Serverprojekt nicht für die Verarbeitung von Controlleraktionen konfiguriert ist:

  • Fügen Sie MVC-Dienste hinzu, indem Sie AddControllers für die Dienstsammlung in der Program-Datei aufrufen:

    builder.Services.AddControllers();
    
  • Fügen Sie Controllerendpunktrouting in der Program-Datei hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen (app):

    app.MapControllers();
    

Um Benutzer*innen die Auswahl einer Kultur für SSR-Komponenten zu ermöglichen, verwenden Sie eine umleitungsbasierte Vorgehensweise mit einer Lokalisierungcookie. Die App behält die vom Benutzer ausgewählte Kultur mithilfe einer Umleitung an einen Controller bei. Der Controller legt die ausgewählte Kultur des Benutzers mit einem cookie fest und leitet den Benutzer wieder an den ursprünglichen URI weiter. Der Prozess ist ähnelt dem Ablauf in einer Web-App, wenn ein Benutzer versucht, auf eine sichere Ressource zuzugreifen: der Benutzer wird an eine Anmeldeseite umgeleitet und dann wieder zur ursprünglichen Ressource geleitet.

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

Warnung

Verwenden Sie das LocalRedirect Aktionsergebnis wie im vorherigen Beispiel gezeigt, um offene Umleitungsangriffe zu verhindern. Weitere Informationen finden Sie unter Verhindern von Open-Redirect-Angriffen in ASP.NET Core.

Fügen Sie die CultureSelector-Komponente der MainLayout-Komponente hinzu. Platzieren Sie das folgende Markup innerhalb des schließenden </main>-Tags in der Components/Layout/MainLayout.razor-Datei:

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

Verwenden Sie die Im Abschnitt Demokomponente gezeigte CultureExample1-Komponente, um zu untersuchen, wie das obige Beispiel funktioniert.

Platzieren Sie im Serverprojekt die folgende CultureServer Komponente, um zu untersuchen, wie die Globalisierung für SSR-Komponenten funktioniert.

Components/Pages/CultureServer.razor:

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

<PageTitle>Culture Server</PageTitle>

<h1>Culture Server</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;
}

Fügen Sie sowohl die CultureClient als auch die CultureServerKomponenten zur Seitenleistennavigation in Components/Layout/NavMenu.razor hinzu:

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

Interaktive Auto-Komponenten

Die Anleitung in diesem Abschnitt funktioniert auch für Komponenten, die den interaktiven automatischen Rendermodus übernehmen:

@rendermode InteractiveAuto

Lokalisierung

Wenn die App die dynamische Kulturauswahl noch nicht unterstützt, fügen Sie der App das Paket Microsoft.Extensions.Localization hinzu.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Clientseitige Lokalisierung

Legen Sie die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Fügen Sie in der Program-Datei den Namespace für System.Globalization am Anfang hinzu:

using System.Globalization;

Fügen Sie den Lokalisierungsdienst von Blazor mit AddLocalization der Dienstsammlung der App hinzu:

builder.Services.AddLocalization();

Serverseitige Lokalisierung

Verwenden Sie Lokalisierungsmiddleware, um die Kultur der App festzulegen.

Wenn die App die dynamische Kulturauswahl noch nicht unterstützt, gehen Sie folgendermaßen vor:

  • Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.
  • Legen Sie die Standardkulturen und die unterstützten Kulturen der App in der Program-Datei fest. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und Costa Rica-Spanisch konfiguriert.
builder.Services.AddLocalization();

Unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline geschieht Folgendes:

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline finden Sie unter ASP.NET Core-Middleware.

  • Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.
  • Geben Sie die standardmäßigen und unterstützten Kulturen der App in Startup.Configure (Startup.cs) fest. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und Costa Rica-Spanisch konfiguriert.

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

In Startup.Configure wird unmittelbar nach dem Hinzufügen der Routing-Middleware zur Verarbeitungspipeline hinzugefügt:

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Startup.Configure finden Sie unter ASP.NET Core-Middleware.

Wenn die App Ressourcen basierend auf der Speicherung einer Kultureinstellung eines Benutzers lokalisieren soll, verwenden Sie eine cookie für die Lokalisierungskultur. Durch Verwendung eines cookie wird sichergestellt, wird sichergestellt, dass die WebSocket-Verbindung die Kultur ordnungsgemäß weitergeben kann. Wenn die Lokalisierungsschemas auf dem URL-Pfad oder der Abfragezeichenfolge basieren, kann das Schema möglicherweise nicht mit WebSockets funktionieren, wodurch das Beibehalten der Kultur fehlschlägt. Daher wird empfohlen, ein cookie für die Lokalisierungskultur zu verwenden. Im Abschnitt Dynamisches Festlegen der serverseitigen Kultur durch Benutzereinstellung dieses Artikels finden Sie einen Razor-Beispielausdruck, der die Kulturauswahl der Benutzer*innen speichert.

Beispiel für lokalisierte Ressourcen

Das Beispiel für lokalisierte Ressourcen in diesem Abschnitt funktioniert mit den obigen Beispielen in diesem Artikel, in denen die unterstützten Kulturen der App Englisch (en) als Standardgebietsschema und Spanisch (es) als vom Benutzer auswählbares oder vom Browser angegebenes alternatives Gebietsschema sind.

Erstellen Sie eine Ressourcendatei für jedes Gebietsschema. Im folgenden Beispiel werden Ressourcen für eine Greeting-Zeichenfolge auf Englisch und Spanisch erstellt:

  • Englisch (en): Hello, World!
  • Spanisch (es): ¡Hola, Mundo!

Hinweis

Die folgende Ressourcendatei kann in Visual Studio hinzugefügt werden, indem Sie mit der rechten Maustaste auf den Pages-Ordner klicken und Hinzufügen>Neues Element>Ressourcendatei auswählen. Nennen Sie die Datei CultureExample2.resx. Geben Sie Daten für einen neuen Eintrag an, wenn der Editor angezeigt wird. Legen Sie Name auf Greeting und Wert auf Hello, World! fest. Speichern Sie die Datei .

Wenn Sie Visual Studio Code verwenden, empfehlen wir die Installation des ResX-Viewers und -Editors von Tim Heuer. Fügen Sie eine leere Datei vom Typ CultureExample2.resx zum Ordner Pages hinzu. Die Erweiterung übernimmt automatisch die Verwaltung der Datei auf der Benutzeroberfläche. Wählen Sie die Schaltfläche Neue Ressource hinzufügen aus. Befolgen Sie die Anweisungen, um einen Eintrag für Greeting (Schlüssel), Hello, World! (Wert) und None (Kommentar) hinzuzufügen. Speichern Sie die Datei . Wenn Sie die Datei schließen und erneut öffnen, wird die Ressource Greeting angezeigt.

Der ResX-Viewer und -Editor von Tim Heuer ist nicht im Besitz von Microsoft, wird nicht von Microsoft verwaltet und ist nicht durch einen Microsoft-Supportvertrag oder eine Microsoft-Lizenz abgedeckt.

Im Folgenden wird eine typische Ressourcendatei veranschaulicht. Sie können Ressourcendateien manuell in den Ordner Pages der App einfügen, wenn Sie keine integrierten Tools mit einer integrierten Entwicklungsumgebung (Integrated Development Environment, IDE) wie dem integrierten Ressourcendatei-Editor von Visual Studio oder Visual Studio Code mit einer Erweiterung zum Erstellen und Bearbeiten von Ressourcendateien verwenden möchten.

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>

Hinweis

Die folgende Ressourcendatei kann in Visual Studio hinzugefügt werden, indem Sie mit der rechten Maustaste auf den Pages-Ordner klicken und Hinzufügen>Neues Element>Ressourcendatei auswählen. Nennen Sie die Datei CultureExample2.es.resx. Geben Sie Daten für einen neuen Eintrag an, wenn der Editor angezeigt wird. Legen Sie Name auf Greeting und Wert auf ¡Hola, Mundo! fest. Speichern Sie die Datei .

Wenn Sie Visual Studio Code verwenden, empfehlen wir die Installation des ResX-Viewers und -Editors von Tim Heuer. Fügen Sie eine leere Datei vom Typ CultureExample2.resx zum Ordner Pages hinzu. Die Erweiterung übernimmt automatisch die Verwaltung der Datei auf der Benutzeroberfläche. Wählen Sie die Schaltfläche Neue Ressource hinzufügen aus. Befolgen Sie die Anweisungen, um einen Eintrag für Greeting (Schlüssel), ¡Hola, Mundo! (Wert) und None (Kommentar) hinzuzufügen. Speichern Sie die Datei . Wenn Sie die Datei schließen und erneut öffnen, wird die Ressource Greeting angezeigt.

Im Folgenden wird eine typische Ressourcendatei veranschaulicht. Sie können Ressourcendateien manuell in den Ordner Pages der App einfügen, wenn Sie keine integrierten Tools mit einer integrierten Entwicklungsumgebung (Integrated Development Environment, IDE) wie dem integrierten Ressourcendatei-Editor von Visual Studio oder Visual Studio Code mit einer Erweiterung zum Erstellen und Bearbeiten von Ressourcendateien verwenden möchten.

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>

Die folgende Komponente veranschaulicht die Verwendung der lokalisierten Greeting-Zeichenfolge mit IStringLocalizer<T>. Das Razor-Markup @Loc["Greeting"] im folgenden Beispiel lokalisiert die Zeichenfolge, die an den Greeting-Wert gebunden ist, der in den vorherigen Ressourcendateien festgelegt ist.

Fügen Sie den Namespace für Microsoft.Extensions.Localization zur _Imports.razor-Datei der App hinzu:

@using Microsoft.Extensions.Localization

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"];
    }
}

Fügen Sie der Navigation in der NavMenu-Komponente (NavMenu.razor) optional ein Menüelement für die CultureExample2-Komponente hinzu.

Referenzquelle für WebAssembly-Kulturanbieter

Um besser zu verstehen, wie das Blazor-Framework die Lokalisierung verarbeitet, sehen Sie sich die Informationen zur WebAssemblyCultureProvider-Klasse in der ASP.NET Core-Referenzquelle an.

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Gemeinsame Ressourcen

Gehen Sie wie folgt vor, um freigegebene Ressourcen für die Lokalisierung zu erstellen:

  • Erstellen Sie eine Dummyklasse mit einem beliebigen Klassennamen. Im folgenden Beispiel:

    • Die App verwendet den BlazorSample-Namespace, und Lokalisierungsressourcen nutzen den BlazorSample.Localization-Namespace.
    • Die Dummyklasse heißt SharedResource.
    • Die Klassendatei wird in einem Ordner vom Typ Localization im Stammverzeichnis der App abgelegt.

    Localization/SharedResource.cs:

    namespace BlazorSample.Localization;
    
    public class SharedResource
    {
    }
    
  • Erstellen Sie die freigegebenen Ressourcendateien mit der BuildaktionEmbedded resource. Im folgenden Beispiel:

    • Die Dateien werden im Ordner Localization mit der Dummyklasse SharedResource (Localization/SharedResource.cs) abgelegt.

    • Benennen Sie die Ressourcendateien so, dass sie dem Namen der Dummyklasse entsprechen. Die folgenden Beispieldateien enthalten eine Standardlokalisierungsdatei und eine Datei für die spanische Lokalisierung (es).

    • Localization/SharedResource.resx

    • Localization/SharedResource.es.resx

    Hinweis

    Localization ist der Ressourcenpfad, der über LocalizationOptions festgelegt werden kann.

  • Um auf die Dummyklasse für ein eingefügtes IStringLocalizer<T>-Element in einer Razor-Komponente zu verweisen, geben Sie entweder eine @using-Anweisung für den Lokalisierungsnamespace an, oder fügen Sie den Lokalisierungsnamespace in den Dummyklassenverweis ein. In den folgenden Beispielen:

    • Im ersten Beispiel wird der Localization-Namespace für die Dummyklasse SharedResource mit einer @using-Anweisung angegeben.
    • Im zweiten Beispiel wird der Namespace der SharedResource-Dummyklasse explizit angegeben.

    Befolgen Sie in einer Razor-Komponente einen der folgenden Ansätze:

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

Weitere Informationen finden Sie unter Globalisierung und Lokalisierung in ASP.NET Core.

Zusätzliche Ressourcen