Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere .NET e .NET Core Support Policy. Per la versione corrente, vedere la versione .NET 10 di questo articolo.
Questo articolo illustra come presentare il contenuto globalizzato e localizzato agli utenti in lingue e culture diverse.
Globalizzazione e localizzazione
Per la globalizzazione, Blazor fornisce la formattazione di numeri e date. Per localizzazione, Blazor esegue il rendering del contenuto usando il sistema delle risorse .NET.
Sono supportati un set limitato di funzionalità di localizzazione di ASP.NET Core:
Supportati:IStringLocalizer e IStringLocalizer<T> sono supportati nelle Blazor app.
Non supportato:IHtmlLocalizer e IViewLocalizer sono funzionalità di ASP.NET Core MVC e non supportate nelle app Blazor.
Per le app di Blazor, i messaggi di convalida localizzati per la convalida dei moduli di usando le annotazioni dei dati sono supportati se vengono implementati DisplayAttribute.ResourceType e ValidationAttribute.ErrorMessageResourceType.
Questo articolo descrive come usare Blazorle funzionalità di globalizzazione e localizzazione basate su:
- Intestazione
Accept-Language, impostata dal browser in base alle preferenze di lingua di un utente nelle impostazioni del browser. - Una cultura definita dall'applicazione non basata sul valore dell'intestazione
Accept-Language. L'impostazione può essere statica per tutti gli utenti o dinamica in base alla logica dell'app. Quando l'impostazione si basa sulla preferenza dell'utente, l'impostazione viene in genere salvata per ricaricare le visite future.
Per altre informazioni generali, vedere le risorse seguenti:
- Globalizzazione e localizzazione in ASP.NET Core
- .NET Fundamentals: Globalization
- nozioni fondamentali .NET: localizzazione
Spesso, i termini lingua e cultura vengono usati in modo intercambiabile quando si gestiscono concetti di globalizzazione e localizzazione.
In questo articolo la lingua fa riferimento alle selezioni effettuate da un utente nelle impostazioni del browser. Le selezioni della lingua dell'utente vengono inviate nelle richieste del browser nell'intestazioneAccept-Language. Le impostazioni del browser usano in genere la parola "lingua" nell'interfaccia utente.
Culture si riferisce ai membri dell'API .NET e Blazor. Ad esempio, la richiesta di un utente può includere l'intestazione Accept-Language che specifica una lingua dal punto di vista dell'utente, ma l'app imposta infine la CurrentCulture proprietà ("culture") dalla lingua richiesta dall'utente. L'API usa in genere la parola "culture" nei nomi dei membri.
Le indicazioni contenute in questo articolo non illustrano l'impostazione dell'attributo del linguaggio HTML (<html lang="...">) della pagina, che usa gli strumenti di accessoblità. È possibile impostare il valore in modo statico assegnando un linguaggio all'attributo lang del <html> tag o a document.documentElement.lang in JavaScript. È possibile impostare dinamicamente il valore di document.documentElement.lang con JS interop.
Nota
Gli esempi di codice in questo articolo adottano i tipi di riferimento nullable (NRT) e l'analisi statica dello stato nullo del compilatore .NET, supportati in ASP.NET Core in .NET 6 o versioni successive. Quando la destinazione è .NET 5 o versioni precedenti, rimuovere la designazione di tipo Null (?) dagli esempi dell'articolo.
Globalizzazione
La @bind direttiva attribute applica i formati e analizza i valori per la visualizzazione in base alla prima lingua preferita dell'utente supportata dall'app.
@bind supporta il @bind:culture parametro per fornire un oggetto System.Globalization.CultureInfo per l'analisi e la formattazione di un valore.
È possibile accedere alla cultura corrente dalla proprietà System.Globalization.CultureInfo.CurrentCulture.
CultureInfo.InvariantCulture viene usato per i tipi di campo seguenti (<input type="{TYPE}" />, dove il {TYPE} segnaposto è il tipo):
datenumber
Tipi di campo precedenti:
- Vengono visualizzati usando le regole di formattazione appropriate basate su browser.
- Non può contenere testo in formato libero.
- Specificare le caratteristiche di interazione dell'utente in base all'implementazione del browser.
Blazor fornisce il supporto predefinito per il rendering dei valori nella cultura attuale. Pertanto, specificare una cultura con @bind:culture non è consigliabile quando si utilizzano i tipi di campo date e number.
I tipi di campo seguenti hanno requisiti di formattazione specifici e non sono supportati da tutti i browser principali, quindi non sono supportati da Blazor:
datetime-localmonthweek
Per il supporto corrente del browser dei tipi precedenti, vedere Can I use.
Per impostazione predefinita, Blazor carica un sottoinsieme dei dati di globalizzazione che contiene la cultura dell'app. Per caricare tutti i dati di globalizzazione, impostare <BlazorWebAssemblyLoadAllGlobalizationData> su true nel file di progetto dell'app (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Supporto .NET globalization e International Components for Unicode (ICU) (Blazor WebAssembly)
Blazor WebAssembly utilizza un'API di globalizzazione ridotta e un set di Componenti internazionali predefiniti per le impostazioni locali Unicode (ICU).
Nelle app WebAssembly (Wasm) quando la modalità invariante della globalizzazione è disabilitata, viene caricato un file di dati ICU. Esistono quattro tipi di base di questi file:
-
icudt.dat: dati completi -
icudt_EFIGS.dat: dati per le impostazioni locali:en-*,fr-FRes-ES,it-IT, ede-DE. -
icudt_CJK.dat: dati per le impostazioni locali:en-*,jako, ezh-*. -
icudt_no_CJK.dat: dati per tutte le località daicudt.dat, esclusoja,ko, ezh-*.
Specificare un file da caricare con la <BlazorIcuDataFileName> proprietà MSBuild nel file di progetto dell'app (.csproj). L'esempio seguente carica il icudt_no_CJK.dat file:
<PropertyGroup>
<BlazorIcuDataFileName>icudt_no_CJK.dat</BlazorIcuDataFileName>
</PropertyGroup>
<BlazorIcuDataFileName> accetta solo un singolo file. Il file può essere un file personalizzato creato dallo sviluppatore. Per creare un file di ICU personalizzato, vedere Icu di globalizzazione WASM: ICU personalizzato.
Se un file non è specificato con <BlazorIcuDataFileName>, la cultura dell'app viene controllata e il file ICU corrispondente viene caricato per la sua cultura. Ad esempio, la en-US cultura comporta il caricamento del icudt_EFIGS.dat file. Per zh-CN, viene usato il icudt_CJK.dat file .
Per altre informazioni, vedere .NET globalization and ICU: ICU on WebAssembly.
Blazor WebAssembly usa un'API di globalizzazione ridotta e un set di Componenti internazionali intrinseci per l'Unicode (ICU). Per altre informazioni, vedere .NET globalization and ICU: ICU on WebAssembly.
Il caricamento di un subset personalizzato di impostazioni locali in un'app Blazor WebAssembly è supportato in .NET 8 o versione successiva. Per altre informazioni, accedere a questa sezione per una versione .NET 8 o successiva di questo articolo.
Globalizzazione invariante
Questa sezione si applica solo agli scenari Blazor lato client.
Se l'app non richiede la localizzazione, configurare l'app per supportare la cultura invariante, che è generalmente basata sull'inglese degli Stati Uniti (en-US). L'uso della globalizzazione invariante riduce le dimensioni di download dell'app e comporta un avvio più rapido dell'app. Impostare la InvariantGlobalization proprietà su true nel file di progetto dell'app (.csproj):
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
In alternativa, configurare la globalizzazione invariante con gli approcci seguenti:
In
runtimeconfig.json:{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }Con una variabile di ambiente:
- Chiave:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT - Valore:
trueo1
- Chiave:
Per ulteriori informazioni, vedere le opzioni di configurazione Runtime per la globalizzazione (documentazione .NET).
Informazioni sul fuso orario
Questa sezione si applica solo agli scenari lato Blazor client.
L'adozione della globalizzazione invariante comporta solo l'uso di nomi di fuso orario non localizzati. Per ridurre il codice e i dati del fuso orario, riducendo le dimensioni di download dell'app e comportando un avvio più rapido dell'app, applicare la <InvariantTimezone> proprietà MSBuild con un valore di true nel file di progetto dell'app:
<PropertyGroup>
<InvariantTimezone>true</InvariantTimezone>
</PropertyGroup>
Nota
<BlazorEnableTimeZoneSupport> esegue l'override di un'impostazione precedente <InvariantTimezone> . È consigliabile rimuovere l'impostazione <BlazorEnableTimeZoneSupport> .
È incluso un file di dati per correggere le informazioni sul fuso orario. Se l'app non richiede questa funzionalità, è consigliabile disabilitarla impostando la <BlazorEnableTimeZoneSupport> proprietà MSBuild su false nel file di progetto dell'app:
<PropertyGroup>
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
</PropertyGroup>
Componente dimostrativo
Il componente seguente CultureExample1 può essere usato per illustrare Blazor i concetti relativi alla globalizzazione e alla localizzazione trattati in questo articolo.
CultureExample1.razor:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></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><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></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;
}
Il formato della stringa numerica (N2) nell'esempio precedente (.ToString("N2")) è un specificatore di formato numerico standard .NET. Il N2 formato è supportato per tutti i tipi numerici, include un separatore di gruppo ed esegue il rendering fino a due posizioni decimali.
Facoltativamente, si può aggiungere una voce di menu al riquadro di spostamento nel componente NavMenu (NavMenu.razor) per il componente CultureExample1.
Impostare dinamicamente la cultura dall'intestazione Accept-Language
Aggiungere il pacchetto Microsoft.Extensions.Localization all'app.
L'intestazione Accept-Language viene impostata dal browser e controllata dalle preferenze di lingua dell'utente nelle impostazioni del browser. Nelle impostazioni del browser, un utente imposta una o più lingue preferite in ordine di preferenza. L'ordine delle preferenze viene utilizzato dal browser per impostare i valori di qualità (q, 0-1) per ogni lingua nell'intestazione. L'esempio seguente specifica l'inglese statunitense, inglese e spagnolo costaricano con una preferenza per l'inglese statunitense o inglese.
Accept-Language: en-US,en; q=0.9,es-CR; q=0.8
La cultura dell'app è impostata dalla prima lingua richiesta che corrisponde a una cultura supportata dall'app.
Nello sviluppo client-side, impostare la proprietà BlazorWebAssemblyLoadAllGlobalizationData su true nel file di progetto dell'app client-side (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Nello sviluppo lato client, l'impostazione dinamica della lingua dall'intestazione Accept-Language non è supportata.
Nota
Se la specifica dell'app necessita di limitare le culture supportate a un elenco esplicito, vedere la sezione Impostazione dinamica della cultura lato client in base alle preferenze dell'utente di questo articolo.
Le app vengono localizzate usando il middleware di localizzazione. Aggiungere servizi di localizzazione all'app con AddLocalization.
Aggiungere la riga seguente al file in Program cui vengono registrati i servizi:
builder.Services.AddLocalization();
Nello sviluppo sul lato server, specificare le culture supportate dall'app prima di qualsiasi middleware che possa controllare la cultura della richiesta. In genere, posizionare il middleware di localizzazione della richiesta immediatamente prima di chiamare MapRazorComponents. L'esempio seguente configura le culture supportate per inglese degli Stati Uniti e spagnolo di Costa Rica.
Nello sviluppo lato server, specifica le culture supportate dell'app immediatamente dopo l'aggiunta del middleware di routing (UseRouting) alla pipeline di elaborazione. L'esempio seguente configura le culture supportate per l'inglese degli Stati Uniti e lo spagnolo costaricano usando l'API seguente.
- AddSupportedCultures aggiunge il set di culture supportate per la globalizzazione (formattazione delle date, dei numeri e delle valute).
- AddSupportedUICultures aggiunge il set delle culture UI supportate per la localizzazione (stringhe tradotte dell'interfaccia utente per il rendering del contenuto).
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CR" })
.AddSupportedUICultures(new[] { "en-US", "es-CR" }));
Nell'esempio precedente, gli stessi formati culturali supportati e le impostazioni della cultura dell'interfaccia utente vengono specificati in un caso specifico in cui l'app viene usata solo negli Stati Uniti e in Costa Rica. In alternativa, un'app può usare un set più ampio di impostazioni culturali per la formattazione di data, numero e valuta, ma fornire solo contenuto localizzato per gli Stati Uniti e la Costa Rica, come illustrato nell'esempio seguente.
var uiCultures = new[] { "en-US", "es-CR" };
var formattingCultures = CultureInfo
.GetCultures(CultureTypes.SpecificCultures)
.Select(c => c.Name)
.ToArray();
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(uiCultures[0])
.AddSupportedCultures(formattingCultures)
.AddSupportedUICultures(uiCultures);
app.UseRequestLocalization(localizationOptions);
Nell'esempio precedente, CultureTypes.SpecificCultures restituisce solo le culture specifiche di un paese o di una regione—come en-US o fr-FR—che dispongono di dati di globalizzazione completi e concreti (incluse date, numeri, calendari e altre interfacce utente culturali) che .NET può utilizzare per una formattazione e un'analisi accurate. Le culture neutre, ad esempio en o fr, potrebbero non avere dati di globalizzazione completi, quindi non sono incluse in questo elenco.
Per informazioni sulla configurazione del middleware di localizzazione nella pipeline middleware del file Program, vedere ASP.NET Core Middleware.
Usare il componente CultureExample1 illustrato nella sezione Componente dimostrativo per studiare il funzionamento della globalizzazione. Eseguire una richiesta con Stati Uniti inglese (en-US). Passare allo spagnolo costa ricano (es-CR) nelle impostazioni della lingua del browser. Richiedere di nuovo la pagina Web.
Quando le impostazioni cultura sono inglese degli Stati Uniti (en-US), il componente sottoposto a rendering usa la formattazione della data mese/giorno (6/7), il formato orario a 12 ore (AM/PM) e i separatori delle migliaia con la virgola nei numeri, con il punto come separatore decimale (1,999.69):
- Data: 6/7/2021 6:45:22 AM
- Numero: 1.999.69
Quando le impostazioni cultura sono spagnolo costa ricano (es-CR), il componente sottoposto a rendering usa la formattazione della data giorno/mese (7/6), l'ora di 24 ore e i separatori di periodo in numeri con una virgola per il valore decimale (1.999,69):
- Data: 6/7/2021 6:49:38
- Numero: 1,999,69
Impostare in modo statico le impostazioni cultura lato client
Impostare la BlazorWebAssemblyLoadAllGlobalizationData proprietà su true nel file di progetto dell'app (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
La configurazione del linker del linguaggio intermedio (IL) per il rendering lato client rimuove le informazioni di internazionalizzazione, ad eccezione dei locali richiesti in modo esplicito. Per altre informazioni, vedere Configurare il linker per ASP.NET Core Blazor.
La cultura dell'app può essere configurata in JavaScript quando Blazor inizia con l'opzione di avvio applicationCultureBlazor. L'esempio seguente configura l'app per l'avvio usando la cultura inglese degli Stati Uniti (en-US).
Impedire l'avvio Blazor automatico aggiungendo autostart="false" al tag di Blazor<script>:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
Nell'esempio precedente il {BLAZOR SCRIPT} segnaposto è il percorso dello script e il Blazor nome del file. Per il percorso dello script, vedere ASP.NET Core Blazor struttura del progetto.
Aggiungere il seguente blocco
Blazor Web App:
<script>
Blazor.start({
webAssembly: {
applicationCulture: 'en-US'
}
});
</script>
Blazor WebAssembly autonomo:
<script>
Blazor.start({
applicationCulture: 'en-US'
});
</script>
Il valore per applicationCulture deve essere conforme al formato del tag di lingua BCP-47. Per altre informazioni sull'avvio di Blazor, vedere ASP.NET Core Blazor startup.
Un'alternativa all'impostazione dell'opzione d'avvio della cultura Blazor consiste nell'impostare la cultura nel codice C#. Impostare CultureInfo.DefaultThreadCurrentCulture e CultureInfo.DefaultThreadCurrentUICulture nel file Program alla stessa cultura.
Aggiungere il System.Globalization namespace al Program file:
using System.Globalization;
Aggiungere le impostazioni della cultura prima della riga che compila ed esegue WebAssemblyHostBuilder (await builder.Build().RunAsync();):
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
Nota
In .NET 9 o versioni precedenti, le app autonome Blazor WebAssembly caricano le risorse di globalizzazione dell'interfaccia utente in base a CultureInfo.DefaultThreadCurrentCulture. Se desideri caricare anche i dati di globalizzazione per la cultura di localizzazione definita da CultureInfo.DefaultThreadCurrentUICulture, aggiorna l'app a .NET 10 o versione successiva.
Usare il componente CultureExample1 illustrato nella sezione Componente dimostrativo per studiare il funzionamento della globalizzazione. Eseguire una richiesta con Stati Uniti inglese (en-US). Passare allo spagnolo costa ricano (es-CR) nelle impostazioni della lingua del browser. Richiedere di nuovo la pagina Web. Quando la lingua richiesta è lo spagnolo costaricano, la cultura dell'app rimane inglese degli Stati Uniti (en-US).
Impostare in modo statico la cultura lato server
Le app sul lato server vengono localizzate usando il middleware di localizzazione. Aggiungere servizi di localizzazione all'app con AddLocalization.
Nel file Program:
builder.Services.AddLocalization();
Specificare la cultura statica nel Program file prima di qualsiasi middleware che potrebbe controllare la cultura della richiesta. In genere, posizionare il Middleware di localizzazione della richiesta immediatamente prima di MapRazorComponents. L'esempio seguente configura l'inglese degli Stati Uniti.
Specificare la cultura statica nel file Program immediatamente dopo aver aggiunto il Routing Middleware (UseRouting) alla pipeline di elaborazione. Esempio di configurazione della lingua inglese degli Stati Uniti:
app.UseRequestLocalization("en-US");
Il valore delle impostazioni cultura per UseRequestLocalization deve essere conforme al formato del tag di lingua BCP-47.
Per informazioni sulla configurazione del middleware di localizzazione nella pipeline middleware del file Program, vedere ASP.NET Core Middleware.
Le app sul lato server vengono localizzate usando il middleware di localizzazione. Aggiungere servizi di localizzazione all'app con AddLocalization.
In Startup.ConfigureServices (Startup.cs):
services.AddLocalization();
Specificare la cultura statica in Startup.Configure (Startup.cs) immediatamente dopo l'aggiunta del middleware di routing alla pipeline di elaborazione. Di seguito un esempio di configurazione per l'inglese (Stati Uniti):
app.UseRequestLocalization("en-US");
Il valore delle impostazioni cultura per UseRequestLocalization deve essere conforme al formato tag linguistico BCP-47.
Per informazioni su come ordinare il Localization Middleware nella pipeline di middleware di Startup.Configure, vedere ASP.NET Core Middleware.
Usare il componente CultureExample1 illustrato nella sezione Componente dimostrativo per studiare il funzionamento della globalizzazione. Eseguire una richiesta con Stati Uniti inglese (en-US). Passare allo spagnolo costa ricano (es-CR) nelle impostazioni della lingua del browser. Richiedere di nuovo la pagina Web. Quando la lingua richiesta è lo spagnolo costaricano, la cultura dell'app rimane inglese degli Stati Uniti (en-US).
Impostare dinamicamente la cultura lato client in base alle preferenze dell'utente
Esempi di posizioni in cui un'app potrebbe archiviare le preferenze di un utente includono nell'archiviazione locale del browser (comune per gli scenari lato client), in una localizzazione cookie o in un database (comune per scenari lato server) o in un servizio esterno collegato a un database esterno e accessibile da un'API Web. Nell'esempio seguente viene illustrato come usare l'archiviazione locale del browser.
Aggiungere il pacchetto Microsoft.Extensions.Localization all'app.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Impostare la BlazorWebAssemblyLoadAllGlobalizationData proprietà su true nel file di progetto:
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Le impostazioni delle culture dell'app per il rendering lato client sono impostate usando l'API Blazor del framework. La selezione delle impostazioni cultura di un utente può essere salvata in modo permanente nell'archiviazione locale del browser.
Fornire JS funzioni dopo il tag Blazor per <script> ottenere e impostare la selezione della cultura dell'utente con l'archiviazione locale del browser:
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Nota
L'esempio precedente inquina il client con funzioni globali. Per un approccio migliore nelle app di produzione, vedere Isolamento JavaScript nei moduli JavaScript.
Aggiungere gli spazi dei nomi per System.Globalization e Microsoft.JSInterop all'inizio del file Program:
using System.Globalization;
using Microsoft.JSInterop;
Rimuovere la riga seguente:
- await builder.Build().RunAsync();
Sostituire la riga precedente con il codice seguente. Il codice aggiunge il servizio di localizzazione di Blazor alla raccolta di servizi dell'app tramite AddLocalization e utilizza l'interoperabilità di JS per effettuare chiamate a JS e recuperare la selezione dell'impostazione culturale dell'utente dalla memoria locale. Se l'archiviazione locale non contiene impostazioni cultura per l'utente, il codice imposta un valore predefinito inglese degli Stati Uniti (en-US).
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Nota
In .NET 9 o versioni precedenti, le app autonome Blazor WebAssembly caricano le risorse di globalizzazione dell'interfaccia utente in base a CultureInfo.DefaultThreadCurrentCulture. Se desideri caricare anche i dati di globalizzazione per la cultura di localizzazione definita da CultureInfo.DefaultThreadCurrentUICulture, aggiorna l'app a .NET 10 o versione successiva.
Il componente seguente CultureSelector illustra come eseguire le azioni seguenti:
- Impostare la selezione della cultura utente nell'archiviazione locale del browser tramite JS interop.
- Ricarica il componente richiesto (
forceLoad: true), che utilizza la cultura aggiornata.
CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
Nota
Per altre informazioni su IJSInProcessRuntime, vedere Chiamare le funzioni JavaScript dai metodi .NET in ASP.NET Core Blazor.
All'interno del tag di chiusura dell'elemento </main> nel componente MainLayout (MainLayout.razor), aggiungere il componente CultureSelector:
<article class="bottom-row px-4">
<CultureSelector />
</article>
Usare il CultureExample1 componente mostrato nella sezione Componente dimostrativo per studiare il funzionamento dell'esempio precedente.
Impostare dinamicamente la cultura lato server in base alle preferenze dell'utente
Esempi di posizioni in cui un'app potrebbe archiviare le preferenze di un utente includono nell'archiviazione locale del browser (comune per gli scenari lato client), in una localizzazione cookie o in un database (comune per scenari lato server) o in un servizio esterno collegato a un database esterno e accessibile da un'API Web. Nell'esempio seguente viene illustrato come usare una localizzazione cookie.
Nota
Nell'esempio seguente si presuppone che l'app adotta l'interattività globale specificando il rendering interattivo lato server (SSR interattivo) nel Routes componente App (Components/App.razor):
<Routes @rendermode="InteractiveServer" />
Se l'app adotta l'interattività per pagina/componente , vedi le osservazioni alla fine di questa sezione per modificare le modalità di rendering dei componenti dell'esempio.
Aggiungere il pacchetto Microsoft.Extensions.Localization all'app.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Le app sul lato server vengono localizzate usando il middleware di localizzazione. Aggiungere servizi di localizzazione all'app con AddLocalization.
Nel file Program:
builder.Services.AddLocalization();
Impostare le culture predefinite e supportate dell'app con RequestLocalizationOptions.
Prima della chiamata a MapRazorComponents nella pipeline di elaborazione della richiesta, inserire il codice seguente:
Dopo l'aggiunta del middleware di routing (UseRouting) alla pipeline di elaborazione delle richieste, inserire il codice seguente:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Per informazioni sull'ordinamento del middleware di localizzazione nella pipeline middleware, vedere ASP.NET Core Middleware.
Nell'esempio seguente viene illustrato come impostare la cultura corrente in un oggetto cookie che può essere letto dal Middleware di Localizzazione.
Per il componente App sono richiesti i seguenti namespaces:
Aggiungere quanto segue all'inizio del file del App componente (Components/App.razor):
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Aggiungere il blocco seguente @code alla fine del componente App file.
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
Le modifiche apportate al Pages/_Host.cshtml file richiedono i namespace seguenti:
Aggiungere il testo seguente al file :
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Per informazioni sull'ordinamento del middleware di localizzazione nella pipeline middleware, vedere ASP.NET Core Middleware.
Se l'app non è configurata per elaborare le azioni del controller:
Aggiungere servizi MVC chiamando AddControllers nella raccolta di servizi nel
Programfile:builder.Services.AddControllers();Aggiungi il routing dell'endpoint del controller nel file
Programchiamando MapControllers su IEndpointRouteBuilder (app):app.MapControllers();
Per fornire un'interfaccia utente che consenta a un utente di selezionare una cultura, usare un approccio basato sul reindirizzamento con localizzazione cookie. L'app conserva le impostazioni culturali selezionate dall'utente tramite un reindirizzamento a un controller. Il controller imposta la cultura selezionata dall'utente nella cookie e reindirizza l'utente all'URI originale. Il processo è simile a quello che accade in un'app Web quando un utente tenta di accedere a una risorsa protetta, in cui l'utente viene reindirizzato a una pagina di accesso e quindi reindirizzato alla risorsa originale.
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);
}
}
Avviso
Usare il risultato dell'azione LocalRedirect , come illustrato nell'esempio precedente, per impedire attacchi di reindirizzamento aperti. Per altre informazioni, vedere Prevent open redirect attacks in ASP.NET Core.
Il componente seguente CultureSelector mostra come chiamare il metodo Set del CultureController con la nuova cultura. Il componente viene inserito nella Shared cartella per l'uso in tutta l'app.
CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
Aggiungere il componente CultureSelector al componente MainLayout. Inserire il markup seguente all'interno del tag di chiusura </main> nel Components/Layout/MainLayout.razor file:
Aggiungere il componente CultureSelector al componente MainLayout. Inserire il markup seguente all'interno del tag di chiusura </main> nel Shared/MainLayout.razor file:
<article class="bottom-row px-4">
<CultureSelector />
</article>
Utilizza il componente
L'esempio precedente presuppone che l'app adotti l'interattività globale specificando la modalità di rendering del server interattivo sul componente Routes nel componente App (Components/App.razor).
<Routes @rendermode="InteractiveServer" />
Se l'app adotta l'interattività per pagina/componente , apportare le modifiche seguenti:
Aggiungere la modalità di rendering del Server Interattivo all'inizio del file del componente
CultureExample1(Components/Pages/CultureExample1.razor):@rendermode InteractiveServerNel layout principale dell'app (
Components/Layout/MainLayout.razor) applicare la modalità di rendering Interactive Server alCultureSelectorcomponente:<CultureSelector @rendermode="InteractiveServer" />
Impostare dinamicamente la cultura in un Blazor Web App in base alle preferenze dell'utente
Questa sezione si applica a Blazor Web App che adottano l'interattività automatica (Server e WebAssembly).
Esempi di posizioni in cui un'app potrebbe archiviare le preferenze di un utente includono nell'archiviazione locale del browser (comune per gli scenari lato client), in una localizzazione cookie o in un database (comune per gli scenari lato server), sia nell'archiviazione locale che in una localizzazione cookie (Blazor Web Apps con componenti server e WebAssembly) o in un servizio esterno collegato a un database esterno e accessibile da un'API Web. Nell'esempio seguente viene illustrato come usare l'archiviazione locale del browser per i componenti di cui è stato eseguito il rendering sul lato client e una localizzazione cookie per i componenti di cui è stato eseguito il rendering sul lato server (SSR).
Aggiornamenti al .Client progetto
Aggiungere il pacchetto Microsoft.Extensions.Localization al progetto .Client.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Impostare la proprietà BlazorWebAssemblyLoadAllGlobalizationData su true nel progetto .Client file.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Aggiungere i namespace per System.Globalization e Microsoft.JSInterop all'inizio del file del progetto Program:
using System.Globalization;
using Microsoft.JSInterop;
Rimuovere la riga seguente:
- await builder.Build().RunAsync();
Sostituire la riga precedente con il codice seguente. Il codice aggiunge Blazor il servizio di localizzazione alla raccolta di servizi dell'app con AddLocalization e utilizza l'interop di JS per chiamare JS e recuperare la selezione della cultura dell'utente dalla memoria locale. Se l'archiviazione locale non contiene impostazioni regionali per l'utente, il codice imposta un valore predefinito inglese degli Stati Uniti (en-US).
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Nota
In .NET 9 o versioni precedenti, le app autonome Blazor WebAssembly caricano le risorse di globalizzazione dell'interfaccia utente in base a CultureInfo.DefaultThreadCurrentCulture. Se desideri caricare anche i dati di globalizzazione per la cultura di localizzazione definita da CultureInfo.DefaultThreadCurrentUICulture, aggiorna l'app a .NET 10 o versione successiva.
Aggiungere il componente seguente CultureSelector al .Client progetto.
Il componente adotta gli approcci seguenti per lavorare per i componenti SSR o CSR:
- Il nome visualizzato di ogni cultura disponibile nell'elenco a discesa viene fornito da un dizionario perché i dati di globalizzazione lato client includono il testo localizzato dei nomi visualizzati delle culture che i dati di globalizzazione lato server forniscono. Ad esempio, la localizzazione lato server visualizza
English (Stati Uniti)quandoen-USè la cultura eIngles ()quando è utilizzata una cultura diversa. Poiché la localizzazione dei nomi visualizzati delle impostazioni cultura non è disponibile con la globalizzazione Blazor WebAssembly, il nome visualizzato per l'inglese degli Stati Uniti nel client per qualsiasi cultura caricata è soloen-US. L'uso di un dizionario personalizzato consente al componente di visualizzare almeno i nomi completi della cultura inglese. - Quando l'utente modifica la cultura, JS interop imposta la cultura nell'archiviazione del browser locale e un'azione del controller aggiorna la localizzazione cookie in base alla cultura. Il controller viene aggiunto all'app più avanti nella sezione Aggiornamenti del progetto Server.
Pages/CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="@selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@cultureDict[culture.Name]</option>
}
</select>
</label>
</p>
@code
{
private Dictionary<string, string> cultureDict =
new()
{
{ "en-US", "English (United States)" },
{ "es-CR", "Spanish (Costa Rica)" }
};
private CultureInfo[] supportedCultures =
[
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
];
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
Nel file .Client del progetto _Imports (_Imports.razor), aggiungere il namespace per i componenti nella cartella Pages, aggiornando il namespace in modo che coincida con il namespace del progetto .Client:
@using BlazorSample.Client.Pages
Nota
Per altre informazioni su IJSInProcessRuntime, vedere Chiamare le funzioni JavaScript dai metodi .NET in ASP.NET Core Blazor.
Nel progetto .Client aggiungere il componente CultureSelector al componente MainLayout. Inserire il markup seguente all'interno del tag di chiusura </main> nel Layout/MainLayout.razor file:
<article class="bottom-row px-4">
<CultureSelector @rendermode="InteractiveAuto" />
</article>
.Client Nel progetto posizionare il componente seguente CultureClient per studiare il funzionamento della globalizzazione per i componenti CSR.
Pages/CultureClient.razor:
@page "/culture-client"
@rendermode InteractiveWebAssembly
@using System.Globalization
<PageTitle>Culture Client</PageTitle>
<h1>Culture Client</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></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><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></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;
}
Nel progetto .Client posizionare il componente CultureServer seguente per studiare il funzionamento della globalizzazione per i componenti SSR.
Pages/CultureServer.razor:
@page "/culture-server"
@rendermode InteractiveServer
@using System.Globalization
<PageTitle>Culture Server</PageTitle>
<h1>Culture Server</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></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><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></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;
}
Usa il componente CultureExample1 alla cartella .Client del progetto di Pages.
Aggiungere i componenti CultureClient, CultureServere CultureExample1 alla barra di navigazione laterale in Layout/NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-server">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Server)
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-client">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Client)
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-example-1">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Auto)
</NavLink>
</div>
Aggiornamenti del progetto server
Aggiungere il pacchetto Microsoft.Extensions.Localization al progetto server.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Le app sul lato server vengono localizzate usando il middleware di localizzazione. Aggiungere servizi di localizzazione all'app con AddLocalization.
Nel file del progetto server Program in cui sono registrati i servizi:
builder.Services.AddLocalization();
Impostare le culture predefinite e supportate dell'app utilizzando RequestLocalizationOptions.
Prima della chiamata a MapRazorComponents nella pipeline di elaborazione della richiesta, inserire il codice seguente:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Nell'esempio seguente viene illustrato come impostare la cultura corrente in un oggetto cookie che può essere letto dal Middleware di localizzazione.
Per il componente App sono necessari i seguenti namespace:
Aggiungere quanto segue all'inizio del file componente App (Components/App.razor):
@using System.Globalization
@using Microsoft.AspNetCore.Localization
La cultura dell'applicazione per il rendering lato cliente viene impostata usando l'API Blazor del framework. La selezione delle impostazioni cultura di un utente può essere resa persistente nell'archiviazione locale del browser per i componenti CSR.
Dopo il tag
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Nota
L'esempio precedente inquina il client con funzioni globali. Per un approccio migliore nelle app di produzione, vedere Isolamento JavaScript nei moduli JavaScript.
Aggiungere il blocco seguente @code alla fine del file del App componente:
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
Se il progetto server non è configurato per elaborare le azioni del controller:
Aggiungere servizi MVC chiamando AddControllers nella raccolta di servizi nel
Programfile:builder.Services.AddControllers();Aggiungere il routing dell'endpoint del controller
Programnel file chiamando MapControllers su IEndpointRouteBuilder (app):app.MapControllers();
Per consentire a un utente di selezionare una cultura per i componenti SSR, utilizzare un approccio basato sul reindirizzamento con una localizzazione. L'app conserva la cultura selezionata dall'utente tramite un reindirizzamento a un controller. Il controller imposta la cultura utente selezionata in un cookie e reindirizza l'utente all'URI originale. Il processo è simile a quello che accade in un'app Web quando un utente tenta di accedere a una risorsa protetta, in cui l'utente viene reindirizzato a una pagina di accesso e quindi reindirizzato alla risorsa originale.
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);
}
}
Avviso
Usare il risultato dell'azione LocalRedirect , come illustrato nell'esempio precedente, per impedire attacchi di reindirizzamento aperti. Per ulteriori informazioni, vedere Impedisci attacchi di reindirizzamento aperto in ASP.NET Core.
Componenti interattivi auto
Le indicazioni contenute in questa sezione funzionano anche per i componenti nelle app che adottano il rendering per pagina/componente e specificano la modalità di rendering automatico interattivo:
@rendermode InteractiveAuto
Localizzazione
Se l'app non supporta già la selezione dinamica delle impostazioni cultura, aggiungere il pacchetto Microsoft.Extensions.Localization all'app.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Localizzazione lato client
Impostare la BlazorWebAssemblyLoadAllGlobalizationData proprietà su true nel file di progetto dell'app (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Nel file Program, aggiungere lo spazio dei nomi di System.Globalization all'inizio del file.
using System.Globalization;
Aggiungere Blazoril servizio di localizzazione alla raccolta di servizi dell'app con AddLocalization:
builder.Services.AddLocalization();
Localizzazione lato server
Usa il middleware di localizzazione per impostare la cultura dell'app.
Se l'app non supporta già la selezione dinamica delle impostazioni cultura:
- Aggiungere servizi di localizzazione all'app con AddLocalization.
- Specifica le culture predefinite e supportate dell'app nel file
Program. L'esempio seguente configura le impostazioni cultura supportate per inglese degli Stati Uniti e spagnolo della Costa Rica.
builder.Services.AddLocalization();
Posizionare il middleware di localizzazione delle richieste prima di qualsiasi middleware che potrebbe verificare la cultura della richiesta. Il middleware va generalmente posizionato immediatamente prima di chiamare MapRazorComponents:
Subito dopo l'aggiunta del middleware di routing (UseRouting) alla pipeline di elaborazione:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Per informazioni sull'ordinamento del middleware di localizzazione nella pipeline middleware, vedere ASP.NET Core Middleware.
- Aggiungere servizi di localizzazione all'app con AddLocalization.
- Specificare le culture predefinite e supportate dell'app in
Startup.Configure(Startup.cs). L'esempio seguente configura le impostazioni cultura supportate per l'inglese degli Stati Uniti e lo spagnolo della Costa Rica.
In Startup.ConfigureServices (Startup.cs):
services.AddLocalization();
In Startup.Configure subito dopo l'aggiunta del middleware di routing (UseRouting) alla pipeline di elaborazione:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Per informazioni sulla configurazione del middleware di localizzazione nella pipeline middleware di Startup.Configure, consultare ASP.NET Core Middleware.
Se l'app deve localizzare le risorse in base alle impostazioni della cultura di un utente, usa la cultura di localizzazione cookie. L'uso di un cookie garantisce che la connessione WebSocket possa propagare correttamente le impostazioni della cultura. Se gli schemi di localizzazione sono basati sul percorso URL o sulla stringa di query, lo schema potrebbe non essere in grado di usare WebSockets, quindi non riuscirà a mantenere persistente la cultura. Pertanto, l'approccio consigliato consiste nell'usare impostazioni culturali di localizzazione cookie. Consultare la sezione sulle impostazioni dinamiche della cultura lato server in base alle preferenze dell'utente di questo articolo per vedere un esempio di espressione Razor che conserva la selezione della cultura dell'utente.
Esempio di risorse localizzate
L'esempio di risorse localizzate in questa sezione funziona con gli esempi precedenti in questo articolo in cui le impostazioni cultura supportate dell'app sono inglese (en) come impostazioni locali predefinite e spagnolo (es) come impostazioni locali alternative selezionabili dall'utente o specificate dal browser.
Creare un file di risorse per ogni impostazione locale. Nell'esempio seguente vengono create risorse per una Greeting stringa in inglese e spagnolo:
- Inglese (
en):Hello, World! - Spagnolo (
es):¡Hola, Mundo!
Nota
È possibile aggiungere il file di risorse seguente in Visual Studio facendo clic con il pulsante destro del mouse sulla cartella Pages e selezionando Aggiungi>Nuovo elemento>Risorse File. Denominare il file CultureExample2.resx. Quando viene visualizzato l'editor, specificare i dati per una nuova voce.
Imposta il Nome su Greeting e il Valore su Hello, World!. Salvare il file.
Se si usa Visual Studio Code, è consigliabile installare Editor e visualizzatore ResX diTim Heuer. Aggiungere un file vuoto CultureExample2.resx alla Pages cartella . L'estensione assume automaticamente la gestione del file nell'interfaccia utente. Selezionare il pulsante Aggiungi nuova risorsa . Segui le istruzioni per aggiungere una voce per Greeting (chiave), Hello, World! (valore) e None (commento). Salvare il file. Se si chiude e si riapri il file, è possibile visualizzare la Greeting risorsa.
Visualizzatore e editor ResX diTim Heuer non è di proprietà o gestito da Microsoft e non è coperto da alcun contratto o licenza supporto tecnico Microsoft.
Di seguito viene illustrato un file di risorse tipico. È possibile inserire manualmente i file di risorse nella cartella Pages dell'app se si preferisce non usare gli strumenti predefiniti con un ambiente di sviluppo integrato (IDE), ad esempio l'editor di file di risorse predefinito di Visual Studio o Visual Studio Code con un'estensione per la creazione e la modifica di file di risorse.
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>
Nota
È possibile aggiungere il file di risorse seguente in Visual Studio facendo clic con il pulsante destro del mouse sulla cartella Pages e selezionando Aggiungi>Nuovo elemento>Risorse File. Denominare il file CultureExample2.es.resx. Quando viene visualizzato l'editor, specificare i dati per una nuova voce. Imposta il Nome su Greeting e il Valore su ¡Hola, Mundo!. Salvare il file.
Se si usa Visual Studio Code, è consigliabile installare Editor e visualizzatore ResX diTim Heuer. Aggiungere un file vuoto CultureExample2.resx alla Pages cartella . L'estensione assume automaticamente la gestione del file nell'interfaccia utente. Selezionare il pulsante Aggiungi nuova risorsa . Seguire le istruzioni per aggiungere una voce con Greeting (chiave), ¡Hola, Mundo! (valore) e None (commento). Salvare il file. Se si chiude e si riapri il file, è possibile visualizzare la Greeting risorsa.
Di seguito viene illustrato un file di risorse tipico. È possibile inserire manualmente i file di risorse nella cartella Pages dell'app se si preferisce non usare gli strumenti predefiniti con un ambiente di sviluppo integrato (IDE), ad esempio l'editor di file di risorse predefinito di Visual Studio o Visual Studio Code con un'estensione per la creazione e la modifica di file di risorse.
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>
Il componente seguente illustra l'uso della stringa localizzata Greeting con IStringLocalizer<T>. Il Razor markup @Loc["Greeting"] nell'esempio seguente localizza la stringa con la chiave associata al Greeting valore impostato nei file di risorse precedenti.
Aggiungi lo spazio dei nomi per Microsoft.Extensions.Localization al file _Imports.razor dell'app.
@using Microsoft.Extensions.Localization
CultureExample2.razor:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
Facoltativamente, aggiungere al componente di navigazione NavMenu una voce di menu per il componente CultureExample2 (NavMenu.razor).
Origine di riferimento del fornitore di cultura WebAssembly
Per comprendere ulteriormente come il framework Blazor elabora la localizzazione, vedere la classe WebAssemblyCultureProvider nell'origine di riferimento ASP.NET Core.
Nota
I collegamenti alla documentazione della sorgente di riferimento .NET in genere caricano il branch predefinito del repository, che rappresenta lo sviluppo in corso della versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Passa ai rami o ai tag. Per altre informazioni, vedere Come selezionare un tag di versione del codice sorgente ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Risorse condivise
Per creare risorse condivise di localizzazione, adottare l'approccio seguente.
Verificare che il pacchetto
Microsoft.Extensions.Localizationfaccia riferimento al progetto.Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.
Verificare che lo spazio dei nomi Microsoft.Extensions.Localization sia disponibile per i componenti Razor del progetto tramite una voce nel file
_Importsdel progetto:@using Microsoft.Extensions.LocalizationCreare una classe fittizia con un nome di classe arbitrario. Nell'esempio seguente :
- L'app usa lo spazio dei nomi
BlazorSamplee gli asset di localizzazione usano lo spazio dei nomiBlazorSample.Localization. - La classe fittizia è denominata
SharedResource. - Il file di classe viene inserito in una
Localizationcartella nella radice dell'app.
Nota
Non usare un file di progettazione generato automaticamente , ad esempio
SharedResources.Designer.cs. La classe fittizia è destinata a fungere da classe di risorse condivise. La presenza di un file di progettazione genera un conflitto tra spazi dei nomi.Localization/SharedResource.cs:namespace BlazorSample.Localization; public class SharedResource { }- L'app usa lo spazio dei nomi
Creare i file di risorse condivise con un'azione di compilazione di
Embedded resource. Nell'esempio seguente :I file vengono inseriti nella
Localizationcartella con la classe fittiziaSharedResource(Localization/SharedResource.cs).Denominare i file di risorse in modo che corrispondano al nome della classe fittizia. I file di esempio seguenti includono un file di localizzazione predefinito e un file per la localizzazione spagnola (
es).Localization/SharedResource.resxLocalization/SharedResource.es.resx
Avviso
Quando si segue l'approccio in questa sezione, non è possibile impostare LocalizationOptions.ResourcesPath e usare IStringLocalizerFactory.Create contemporaneamente per caricare le risorse.
Per fare riferimento alla dummy class per un IStringLocalizer<T> iniettato in un componente Razor, inserire una
@usingdirettiva per lo spazio dei nomi di localizzazione o includere lo spazio dei nomi di localizzazione nel riferimento alla dummy class. Negli esempi seguenti:- Il primo esempio definisce lo spazio dei nomi
Localizationper la classe fittiziaSharedResourcecon una direttiva@using. - Il secondo esempio indica in modo esplicito lo
SharedResourcespazio dei nomi della classe fittizia.
In un Razor componente usare uno degli approcci seguenti:
@using Localization @inject IStringLocalizer<SharedResource> Loc@inject IStringLocalizer<Localization.SharedResource> Loc- Il primo esempio definisce lo spazio dei nomi
Per altre indicazioni, vedere Globalization and localization in ASP.NET Core.
Override della posizione usando il pannello "Sensori" negli strumenti di sviluppo
Quando si utilizza la sostituzione della posizione tramite il riquadro Sensors negli strumenti di sviluppo di Google Chrome o Microsoft Edge, la lingua di fallback si resetta dopo il prerendering. Evitare di impostare la lingua usando il riquadro Sensori durante il test. Impostare la lingua usando le impostazioni della lingua del browser.
Per altre informazioni, vedere Blazor Localizzazione non funziona con InteractiveServer (dotnet/aspnetcore #53707)..
Risorse aggiuntive
- ASP.NET Core Blazor percorso di base dell'app
- Globalizzazione e localizzazione in ASP.NET Core
- Globalizzazione e localizzazione delle applicazioni .NET
- Risorse nei file .resx
- Localizzazione e tipi generici
-
La chiamata
InvokeAsync(StateHasChanged)provoca il ritorno alla cultura predefinita della pagina (dotnet/aspnetcore #28521) -
Blazor La localizzazione non funziona con InteractiveServer (
dotnet/aspnetcore#53707) (override della posizione usando il riquadro "Sensori")