Globalisierung und Lokalisierung in ASP.NET Core Blazor

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

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:

✔️ IStringLocalizer und IStringLocalizer<T> werden in Blazor-Apps 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:

Hinweis

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.

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.

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.

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

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 Shared/NavMenu.razor für die CultureExample1-Komponente optional ein Menüelement hinzu.

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

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 chilenisches Spanisch mit Bevorzugung von US-Englisch oder Englisch angegeben:

Accept-Language: en-US,en;q=0.9,es-CL;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 die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Hinweis

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

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

In Program.cs:

builder.Services.AddLocalization();

Geben Sie unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline die unterstützten Kulturen der App in Program.cs an. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 chilenischem Spanisch (es-CL). 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 chilenisches Spanisch (es-CL) 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 Kultur

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

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

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 in wwwroot/index.html, dass Blazor automatisch gestartet wird, indem Sie autostart="false" zum <script>-Tag von Blazor hinzufügen:

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Fügen Sie den folgenden <script>-Block hinter dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag hinzu:

    <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 Program.cs auf dieselbe Kultur fest.

Fügen Sie den System.Globalization-Namespace zu Program.cs 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.

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

In Program.cs:

builder.Services.AddLocalization();

Geben Sie unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline die statische Kultur in Program.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 Program.cs 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 chilenischem Spanisch (es-CL). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache chilenisches Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Dynamisches Festlegen der Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden 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 in einer Blazor WebAssembly-App wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers kann im lokalen Browserspeicher gespeichert werden.

Geben Sie in der wwwroot/index.html-Datei nach dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag JS-Funktionen an, um die Kulturauswahl des Benutzers im lokalem Browserspeicher abzurufen und festzulegen:

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

Hinweis

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

Fügen Sie die Namespaces für System.Globalization und Microsoft.JSInterop am Anfang von Program.cs hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile aus Program.cs:

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

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

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

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

await host.RunAsync();

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

Die CultureSelector-Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

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

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

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

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

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

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

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

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden und über eine Web-API zugänglich ist. Das folgende Beispiel veranschaulicht, wie ein Lokalisierungs-cookie verwendet wird.

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.

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

In Program.cs:

builder.Services.AddLocalization();

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

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

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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.

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

Pages/_Host.cshtml:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 Program.cs aufrufen:

    builder.Services.AddControllers();
    
  • Fügen Sie das Controllerendpunktrouting in Program.cs hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen:

    app.MapControllers();
    

    Das folgende Beispiel zeigt den Aufruf von UseEndpoints, nachdem die Zeile hinzugefügt wurde:

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

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 Ergebnis der LocalRedirect-Aktion, um Angriffe durch offene Umleitungen 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.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

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

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

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

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

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

Fügen Sie im schließenden Tag </main> in Shared/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.

Lokalisierung

Fügen Sie der App das Microsoft.Extensions.Localization-Paket hinzu, wenn die App wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels beschrieben noch keine Kulturauswahl unterstützt.

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 der App (.csproj) auf true fest:

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

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

using System.Globalization;

Fügen Sie den Lokalisierungsdienst von Blazor mit AddLocalization in Program.cs der Dienstsammlung der App hinzu:

builder.Services.AddLocalization();

Verwenden Sie Lokalisierungsmiddleware, um die Kultur der App festzulegen.

Gehen Sie folgendermaßen vor, wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt:

  • Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.
  • Legen Sie die Standardkulturen und unterstützten Kulturen der App in Program.cs fest. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert.

In Program.cs:

builder.Services.AddLocalization();

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

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 Kultur durch Benutzereinstellung dieses Artikels finden Sie einen Razor-Beispielausdruck, der die Kulturauswahl des Benutzers speichert.

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 Ressourcen für jedes Gebietsschema. Im folgenden Beispiel werden Ressourcen für eine Greeting-Standardzeichenfolge erstellt:

  • Englisch: 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 des Projekts 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 .

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

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

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

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

<h2>Greeting</h2>

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

<p>
    @greeting
</p>

@code {
    private string? greeting;

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

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

Referenzquelle für 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

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:

✔️ IStringLocalizer und IStringLocalizer<T> werden in Blazor-Apps 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:

Hinweis

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.

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.

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.

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

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 Shared/NavMenu.razor für die CultureExample1-Komponente optional ein Menüelement hinzu.

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

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 chilenisches Spanisch mit Bevorzugung von US-Englisch oder Englisch angegeben:

Accept-Language: en-US,en;q=0.9,es-CL;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 die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Hinweis

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

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

In Program.cs:

builder.Services.AddLocalization();

Geben Sie unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline die unterstützten Kulturen der App in Program.cs an. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 chilenischem Spanisch (es-CL). 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 chilenisches Spanisch (es-CL) 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 Kultur

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

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

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 in wwwroot/index.html, dass Blazor automatisch gestartet wird, indem Sie autostart="false" zum <script>-Tag von Blazor hinzufügen:

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Fügen Sie den folgenden <script>-Block hinter dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag hinzu:

    <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 Program.cs auf dieselbe Kultur fest.

Fügen Sie den System.Globalization-Namespace zu Program.cs 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.

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

In Program.cs:

builder.Services.AddLocalization();

Geben Sie unmittelbar nach dem Hinzufügen der Routingmiddleware zur Verarbeitungspipeline die statische Kultur in Program.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 Program.cs 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 chilenischem Spanisch (es-CL). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache chilenisches Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Dynamisches Festlegen der Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden 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 in einer Blazor WebAssembly-App wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers kann im lokalen Browserspeicher gespeichert werden.

Geben Sie in der wwwroot/index.html-Datei nach dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag JS-Funktionen an, um die Kulturauswahl des Benutzers im lokalem Browserspeicher abzurufen und festzulegen:

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

Hinweis

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

Fügen Sie die Namespaces für System.Globalization und Microsoft.JSInterop am Anfang von Program.cs hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile aus Program.cs:

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

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

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

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

await host.RunAsync();

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

Die CultureSelector-Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

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

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

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

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

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

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

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

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden und über eine Web-API zugänglich ist. Das folgende Beispiel veranschaulicht, wie ein Lokalisierungs-cookie verwendet wird.

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.

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

In Program.cs:

builder.Services.AddLocalization();

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

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

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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.

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

Pages/_Host.cshtml:

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

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

Im Beispiel oben ist der Platzhalter {NAMESPACE} der Assemblyname der App.

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 Program.cs aufrufen:

    builder.Services.AddControllers();
    
  • Fügen Sie das Controllerendpunktrouting in Program.cs hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen:

    app.MapControllers();
    

    Das folgende Beispiel zeigt den Aufruf von UseEndpoints, nachdem die Zeile hinzugefügt wurde:

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

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 Ergebnis der LocalRedirect-Aktion, um Angriffe durch offene Umleitungen 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.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

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

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

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

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

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

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

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

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

Lokalisierung

Fügen Sie der App das Microsoft.Extensions.Localization-Paket hinzu, wenn die App wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels beschrieben noch keine Kulturauswahl unterstützt.

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 der App (.csproj) auf true fest:

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

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

using System.Globalization;

Fügen Sie den Lokalisierungsdienst von Blazor mit AddLocalization in Program.cs der Dienstsammlung der App hinzu:

builder.Services.AddLocalization();

Verwenden Sie Lokalisierungsmiddleware, um die Kultur der App festzulegen.

Gehen Sie folgendermaßen vor, wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt:

  • Fügen Sie der App mit AddLocalization Lokalisierungsdienste hinzu.
  • Legen Sie die Standardkulturen und unterstützten Kulturen der App in Program.cs fest. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert.

In Program.cs:

builder.Services.AddLocalization();

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

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

app.UseRequestLocalization(localizationOptions);

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Program.cs 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 Kultur durch Benutzereinstellung dieses Artikels finden Sie einen Razor-Beispielausdruck, der die Kulturauswahl des Benutzers speichert.

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 Ressourcen für jedes Gebietsschema. Im folgenden Beispiel werden Ressourcen für eine Greeting-Standardzeichenfolge erstellt:

  • Englisch: 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 des Projekts 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 .

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

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

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

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

<h2>Greeting</h2>

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

<p>
    @greeting
</p>

@code {
    private string? greeting;

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

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

Referenzquelle für 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

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:

✔️ IStringLocalizer und IStringLocalizer<T> werden in Blazor-Apps 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:

Hinweis

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.

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.

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.

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

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 Shared/NavMenu.razor für die CultureExample1-Komponente optional ein Menüelement hinzu.

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

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 chilenisches Spanisch mit Bevorzugung von US-Englisch oder Englisch angegeben:

Accept-Language: en-US,en;q=0.9,es-CL;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 die BlazorWebAssemblyLoadAllGlobalizationData-Eigenschaft in der Projektdatei der App (.csproj) auf true fest:

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

Hinweis

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

Blazor Server-Apps werden mit 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 unterstützten Kulturen der App in Startup.Configure (Startup.cs) an. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert:

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

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 chilenischem Spanisch (es-CL). 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 chilenisches Spanisch (es-CL) 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 Kultur

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

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

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 in wwwroot/index.html, dass Blazor automatisch gestartet wird, indem Sie autostart="false" zum <script>-Tag von Blazor hinzufügen:

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    
  • Fügen Sie den folgenden <script>-Block hinter dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag hinzu:

    <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 Program.cs auf dieselbe Kultur fest.

Fügen Sie den System.Globalization-Namespace zu Program.cs 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.

Blazor Server-Apps werden mit 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 chilenischem Spanisch (es-CL). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache chilenisches Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Dynamisches Festlegen der Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden 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 in einer Blazor WebAssembly-App wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers kann im lokalen Browserspeicher gespeichert werden.

Geben Sie in der wwwroot/index.html-Datei nach dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag JS-Funktionen an, um die Kulturauswahl des Benutzers im lokalem Browserspeicher abzurufen und festzulegen:

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

Hinweis

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

Fügen Sie die Namespaces für System.Globalization und Microsoft.JSInterop am Anfang von Program.cs hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile aus Program.cs:

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

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

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

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

await host.RunAsync();

Wichtig

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

Die folgende CultureSelector-Komponente veranschaulicht, wie Sie die Kulturauswahl des Benutzers über JS-Interop im lokalen Browserspeicher festlegen. Die Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

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

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

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

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

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

Fügen Sie im schließenden </div>-Tag des <div class="main">-Elements in Shared/MainLayout.razor die CultureSelector-Komponente hinzu:

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

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden und über eine Web-API zugänglich ist. Das folgende Beispiel veranschaulicht, wie ein Lokalisierungs-cookie verwendet wird.

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.

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

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

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

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

var supportedCultures = new[] { "en-US", "es-CL" };
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.

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

Fügen Sie am Anfang der Pages/_Host.cshtml-Datei die folgenden Namespaces hinzu:

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

Fügen Sie unmittelbar nach dem öffnenden <body>-Tag von Pages/_Host.cshtml den folgenden Razor-Ausdruck hinzu:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Startup.Configure 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 Startup.ConfigureServices aufrufen:

    services.AddControllers();
    
  • Fügen Sie das Controllerendpunktrouting in Startup.Configure hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen:

    endpoints.MapControllers();
    

    Das folgende Beispiel zeigt den Aufruf von UseEndpoints, nachdem die Zeile hinzugefügt wurde:

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

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 Ergebnis der LocalRedirect-Aktion, um Angriffe durch offene Umleitungen zu verhindern. Weitere Informationen finden Sie unter Verhindern von Open-Redirect-Angriffen in ASP.NET Core.

Die folgende CultureSelector-Komponente veranschaulicht das Durchführen einer anfänglichen Umleitung, wenn der Benutzer eine Kultur auswählt. Die Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

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

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

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

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

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

Fügen Sie im schließenden </div>-Tag des <div class="main">-Elements in Shared/MainLayout.razor die CultureSelector-Komponente hinzu:

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

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

Lokalisierung

Fügen Sie der App das Microsoft.Extensions.Localization-Paket hinzu, wenn die App wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels beschrieben noch keine Kulturauswahl unterstützt.

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 der App (.csproj) auf true fest:

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

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

using System.Globalization;

Fügen Sie den Lokalisierungsdienst von Blazor mit AddLocalization in Program.cs der Dienstsammlung der App hinzu:

builder.Services.AddLocalization();

Verwenden Sie Lokalisierungsmiddleware, um die Kultur der App festzulegen.

Gehen Sie folgendermaßen vor, wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt:

  • 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 chilenisches 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-CL" };
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 Kultur durch Benutzereinstellung dieses Artikels finden Sie einen Razor-Beispielausdruck für die Pages/_Host.cshtml-Datei, der die Kulturauswahl des Benutzers speichert.

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 Ressourcen für jedes Gebietsschema. Im folgenden Beispiel werden Ressourcen für eine Greeting-Standardzeichenfolge erstellt:

  • Englisch: 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 des Projekts 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 .

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

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

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

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

<h2>Greeting</h2>

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

<p>
    @greeting
</p>

@code {
    private string greeting;

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

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

Referenzquelle für 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

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:

✔️ IStringLocalizer und IStringLocalizer<T> werden in Blazor-Apps 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:

Hinweis

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.

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.

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.

Pages/CultureExample1.razor:

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

<h1>Culture Example 1</h1>

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

<h2>Rendered values</h2>

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

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

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

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

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

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

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

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

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 Shared/NavMenu.razor für die CultureExample1-Komponente optional ein Menüelement hinzu.

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

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 chilenisches Spanisch mit Bevorzugung von US-Englisch oder Englisch angegeben:

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

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

Blazor Server-Apps werden mit 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 unterstützten Kulturen der App in Startup.Configure (Startup.cs) an. Im folgenden Beispiel werden unterstützte Kulturen für US-Englisch und chilenisches Spanisch konfiguriert:

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

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 chilenischem Spanisch (es-CL). 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 chilenisches Spanisch (es-CL) 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 Kultur

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

Blazor Server-Apps werden mit 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 chilenischem Spanisch (es-CL). Fordern Sie die Webseite erneut an. Wenn die angeforderte Sprache chilenisches Spanisch ist, bleibt die Kultur der App US-Englisch (en-US).

Dynamisches Festlegen der Kultur durch Benutzereinstellung

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden 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.

Die Kultur der App in einer Blazor WebAssembly-App wird mithilfe der API des Blazor-Frameworks festgelegt. Die Kulturauswahl eines Benutzers kann im lokalen Browserspeicher gespeichert werden.

Geben Sie in der wwwroot/index.html-Datei nach dem <script>-Tag von Blazor und vor dem schließenden </body>-Tag JS-Funktionen an, um die Kulturauswahl des Benutzers im lokalem Browserspeicher abzurufen und festzulegen:

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

Fügen Sie die Namespaces für System.Globalization und Microsoft.JSInterop am Anfang von Program.cs hinzu:

using System.Globalization;
using Microsoft.JSInterop;

Entfernen Sie die folgende Zeile aus Program.cs:

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

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

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

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

await host.RunAsync();

Wichtig

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

Die folgende CultureSelector-Komponente veranschaulicht, wie Sie die Kulturauswahl des Benutzers über JS-Interop im lokalen Browserspeicher festlegen. Die Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

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

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

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

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

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

Fügen Sie im schließenden </div>-Tag des <div class="main">-Elements in Shared/MainLayout.razor die CultureSelector-Komponente hinzu:

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

Beispiele für Speicherorte, an denen eine App die Einstellung eines Benutzers speichern kann, sind der lokaler Speicher im Browser (in Blazor WebAssembly-Apps üblich), in einem cookie oder in einer Datenbank für die Lokalisierung (in Blazor Server-Apps üblich) oder in einem externen Dienst, der an eine externe Datenbank angebunden und über eine Web-API zugänglich ist. Das folgende Beispiel veranschaulicht, wie ein Lokalisierungs-cookie verwendet wird.

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.

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

In Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

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

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

var supportedCultures = new[] { "en-US", "es-CL" };
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.

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

Fügen Sie am Anfang der Pages/_Host.cshtml-Datei die folgenden Namespaces hinzu:

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

Fügen Sie unmittelbar nach dem öffnenden <body>-Tag von Pages/_Host.cshtml den folgenden Razor-Ausdruck hinzu:

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

Informationen zur Anordnung der Lokalisierungsmiddleware in der Middlewarepipeline von Startup.Configure 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 Startup.ConfigureServices aufrufen:

    services.AddControllers();
    
  • Fügen Sie das Controllerendpunktrouting in Startup.Configure hinzu, indem Sie MapControllers in IEndpointRouteBuilder aufrufen:

    endpoints.MapControllers();
    

    Das folgende Beispiel zeigt den Aufruf von UseEndpoints, nachdem die Zeile hinzugefügt wurde:

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

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 Ergebnis der LocalRedirect-Aktion, um Angriffe durch offene Umleitungen zu verhindern. Weitere Informationen finden Sie unter Verhindern von Open-Redirect-Angriffen in ASP.NET Core.

Die folgende CultureSelector-Komponente veranschaulicht das Durchführen einer anfänglichen Umleitung, wenn der Benutzer eine Kultur auswählt. Die Komponente wird zur Verwendung in der App im Shared-Ordner abgelegt.

Shared/CultureSelector.razor:

@using  System.Globalization
@inject NavigationManager Navigation

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

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

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

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

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

Fügen Sie im schließenden </div>-Tag des <div class="main">-Elements in Shared/MainLayout.razor die CultureSelector-Komponente hinzu:

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

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

Lokalisierung

Fügen Sie der App das Microsoft.Extensions.Localization-Paket hinzu, wenn die App wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels beschrieben noch keine Kulturauswahl unterstützt.

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.

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

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

using System.Globalization;

Fügen Sie den Lokalisierungsdienst von Blazor mit AddLocalization in Program.cs der Dienstsammlung der App hinzu:

builder.Services.AddLocalization();

Verwenden Sie Lokalisierungsmiddleware, um die Kultur der App festzulegen.

Gehen Sie folgendermaßen vor, wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt:

  • 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 chilenisches 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-CL" };
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 Kultur durch Benutzereinstellung dieses Artikels finden Sie einen Razor-Beispielausdruck für die Pages/_Host.cshtml-Datei, der die Kulturauswahl des Benutzers speichert.

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 Ressourcen für jedes Gebietsschema. Im folgenden Beispiel werden Ressourcen für eine Greeting-Standardzeichenfolge erstellt:

  • Englisch: 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 des Projekts 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 .

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

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

Pages/CultureExample2.razor:

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

<h1>Culture Example 2</h1>

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

<h2>Greeting</h2>

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

<p>
    @greeting
</p>

@code {
    private string greeting;

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

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

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