Globalisierung und Lokalisierung in ASP.NET Core Blazor

Razor-Komponenten können globalisierte und lokalisierte Inhalte für Benutzer 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.

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

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 @bind-Attributrichtlinie wendet Formate an und analysiert Werte für die Anzeige basierend auf der ersten bevorzugten Sprache des Benutzers, die die App unterstützt. @bind unterstützt den Parameter @bind:culture, um eine System.Globalization.CultureInfo für das Analysieren und Formatieren von Werten bereitzustellen.

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample1-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-1">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 1
    </NavLink>
</li>

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>

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 applicationCulture Blazor-Startoption 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 Blazor-Start finden Sie unter ASP.NET Core Blazor: Startup.

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

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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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.

Beispiel:

export function getBlazorCulture() {
  return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
  window.localStorage['BlazorCulture'] = value;
};

Wenn Sie die obigen Funktionen verwenden, können Sie die JS-Interopaufrufe in diesem Abschnitt von blazorCulture.get in getBlazorCulture und von blazorCulture.set in setBlazorCulture ändern.

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

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 JSRuntime
@inject NavigationManager Nav

<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)JSRuntime;
                js.InvokeVoid("blazorCulture.set", value.Name);

                Nav.NavigateTo(Nav.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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />
</ItemGroup>

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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

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

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

Fügen Sie unmittelbar nach dem öffnenden <body>-Tag von Pages/_Layout.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 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 offenen Umleitungsangriffen 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 Nav

<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(Nav.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

Wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt, fügen Sie der Projektdatei der App (.csproj) einen Paketverweis für das Microsoft.Extensions.Localization-Paket hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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 für die Pages/_Layout.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>.

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample2-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-2">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 2
    </NavLink>
</li>

Zusätzliche Ressourcen

Razor-Komponenten können globalisierte und lokalisierte Inhalte für Benutzer 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.

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

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 @bind-Attributrichtlinie wendet Formate an und analysiert Werte für die Anzeige basierend auf der ersten bevorzugten Sprache des Benutzers, die die App unterstützt. @bind unterstützt den Parameter @bind:culture, um eine System.Globalization.CultureInfo für das Analysieren und Formatieren von Werten bereitzustellen.

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample1-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-1">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 1
    </NavLink>
</li>

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>

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 applicationCulture Blazor-Startoption 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 Blazor-Start finden Sie unter ASP.NET Core Blazor: Startup.

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

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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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.

Beispiel:

export function getBlazorCulture() {
  return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
  window.localStorage['BlazorCulture'] = value;
};

Wenn Sie die obigen Funktionen verwenden, können Sie die JS-Interopaufrufe in diesem Abschnitt von blazorCulture.get in getBlazorCulture und von blazorCulture.set in setBlazorCulture ändern.

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

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 JSRuntime
@inject NavigationManager Nav

<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)JSRuntime;
                js.InvokeVoid("blazorCulture.set", value.Name);

                Nav.NavigateTo(Nav.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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />
</ItemGroup>

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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.SetDefaultCulture 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 offenen Umleitungsangriffen 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 Nav

<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(Nav.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

Wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt, fügen Sie der Projektdatei der App (.csproj) einen Paketverweis für das Microsoft.Extensions.Localization-Paket hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample2-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-2">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 2
    </NavLink>
</li>

Zusätzliche Ressourcen

Razor-Komponenten können globalisierte und lokalisierte Inhalte für Benutzer 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.

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

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 @bind-Attributrichtlinie wendet Formate an und analysiert Werte für die Anzeige basierend auf der ersten bevorzugten Sprache des Benutzers, die die App unterstützt. @bind unterstützt den Parameter @bind:culture, um eine System.Globalization.CultureInfo für das Analysieren und Formatieren von Werten bereitzustellen.

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample1-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-1">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 1
    </NavLink>
</li>

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 ASP.NET Core Blazor.

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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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

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 JSRuntime
@inject NavigationManager Nav

<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)JSRuntime;
                js.InvokeVoid("blazorCulture.set", value.Name);

                Nav.NavigateTo(Nav.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 einen Paketverweis für das Microsoft.Extensions.Localization-Paket in der Projektdatei der App (.csproj) hinzu:

<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />
</ItemGroup>

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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.SetDefaultCulture 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 offenen Umleitungsangriffen 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 Nav

<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(Nav.Uri)
                    .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
                var cultureEscaped = Uri.EscapeDataString(value.Name);
                var uriEscaped = Uri.EscapeDataString(uri);

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

Wenn die App noch keine Kulturauswahl wie im Abschnitt Dynamisches Festlegen der Kultur durch Benutzereinstellung dieses Artikels unterstützt, fügen Sie der Projektdatei der App (.csproj) einen Paketverweis für das Microsoft.Extensions.Localization-Paket hinzu:

<PackageReference Include="Microsoft.Extensions.Localization" Version="{VERSION}" />

Der {VERSION}-Platzhalter im obigen Paketverweis ist die Version des Pakets.

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 ASP.NET Core Blazor.

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

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 dem <ul>-Navigationsmenüelement in Shared/NavMenu.razor für die CultureExample2-Komponente ein Listenelement hinzu:

<li class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-2">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Culture Example 2
    </NavLink>
</li>

Zusätzliche Ressourcen