Condividi tramite


Globalizzazione e localizzazione in ASP.NET Core

Note

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Warning

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya

Un sito Web multilingue consente a un sito Web di raggiungere un pubblico più ampio. AP.NET Core offre servizi e middleware per la localizzazione in diverse lingue e culture.

Per indicazioni sulla localizzazione fornite da Blazor, che aggiungono o sostituiscono le indicazioni di questo articolo, vedere globalizzazione e localizzazione di ASP.NET CoreBlazor.

Terms

  • Globalizzazione (G11N): processo che consente a un'app di supportare lingue e aree diverse. L'abbreviazione deriva dalla prima e dall'ultima lettera e dal numero di lettere tra di esse.
  • Localizzazione (L10N): processo di personalizzazione di un'app globalizzata per lingue e aree specifiche.
  • Internazionalizzazione (I18N): globalizzazione e localizzazione.
  • Cultura: una lingua e, facoltativamente, una regione.
  • Cultura neutra: Una cultura che ha una lingua specificata, ma non una regione (ad esempio "en", "es").
  • Cultura specifica: Una cultura che ha una lingua e una regione specificate (ad esempio, "en-US", "en-GB", "es-CL").
  • Cultura padre: la cultura neutra che contiene una cultura specifica, ad esempio "en" è la cultura padre di "en-US" e "en-GB".
  • Locale: Un locale è lo stesso di una cultura.

Codici lingua e paese/area geografica

Il formato RFC 4646 per il nome cultura è <language code>-<country/region code>, dove <language code> identifica la lingua e <country/region code> identifica la sottocultura. Ad esempio, es-CL per spagnolo (Cile), en-US per inglese (Stati Uniti) e en-AU per inglese (Australia). RFC 4646 è la combinazione di un codice di cultura in lettere minuscole di due lettere ISO 639 associato a una lingua e un codice di cultura secondaria in lettere maiuscole di due lettere ISO 3166 associato a un paese o un'area. Per ulteriori informazioni, vedere System.Globalization.CultureInfo.

Attività per localizzare un'app

La globalizzazione e la localizzazione di un'app comporta le attività seguenti:

Visualizzare o scaricare il codice di esempio (procedura per il download)

Risorse aggiuntive

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya

Un sito Web multilingue consente a un sito Web di raggiungere un pubblico più ampio. AP.NET Core offre servizi e middleware per la localizzazione in diverse lingue e culture.

Terms

  • Globalizzazione (G11N): processo che consente a un'app di supportare lingue e aree diverse. L'abbreviazione deriva dalla prima e dall'ultima lettera e dal numero di lettere tra di esse.
  • Localizzazione (L10N): processo di personalizzazione di un'app globalizzata per lingue e aree specifiche.
  • Internazionalizzazione (I18N): globalizzazione e localizzazione.
  • Cultura: una lingua e, facoltativamente, una regione.
  • Cultura neutra: una cultura che ha una lingua specificata, ma non una regione (ad esempio "en", "es").
  • Cultura specifica: Una cultura che ha una lingua e una regione specificate (ad esempio, "en-US", "en-GB", "es-CL").
  • Cultura padre: la cultura neutra che contiene una cultura specifica, ad esempio "en" è la cultura padre di "en-US" e "en-GB".
  • Locale: Un locale è lo stesso di una cultura.

Codici lingua e paese/area geografica

Il formato RFC 4646 per il nome cultura è <language code>-<country/region code>, dove <language code> identifica la lingua e <country/region code> identifica la sottocultura. Ad esempio, es-CL per spagnolo (Cile), en-US per inglese (Stati Uniti) e en-AU per inglese (Australia). RFC 4646 è la combinazione di un codice di cultura in lettere minuscole di due lettere ISO 639 associato a una lingua e un codice di cultura secondaria in lettere maiuscole di due lettere ISO 3166 associato a un paese o un'area. Per ulteriori informazioni, vedere System.Globalization.CultureInfo.

Attività per localizzare un'app

La globalizzazione e la localizzazione di un'app comporta le attività seguenti:

Visualizzare o scaricare il codice di esempio (procedura per il download)

Risorse aggiuntive

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya

Un sito web multilingue consente al sito di raggiungere un pubblico più ampio. AP.NET Core offre servizi e middleware per la localizzazione in diverse lingue e culture.

L'internazionalizzazione implica System.Globalization e localizzazione. La globalizzazione è il processo di progettazione di app che supportano culture diverse. La globalizzazione aggiunge supporto per l'input, la visualizzazione e l'output di una specifica serie di script della lingua legati a determinate aree geografiche.

La localizzazione è il processo di adattamento di un'app globalizzata, già elaborata per essere localizzata, a una cultura/locale particolari. Per altre informazioni, vedere Termini relativi alla globalizzazione e alla localizzazione nella parte finale di questo documento.

La localizzazione dell'app comporta quanto segue:

  1. Rendere localizzabile il contenuto dell'app
  2. Fornire le risorse localizzate per le lingue e le culture supportate
  3. Implementare una strategia per la selezione della lingua/cultura per ogni richiesta

Visualizzare o scaricare il codice di esempio (procedura per il download)

Rendere localizzabile il contenuto dell'app

IStringLocalizer e IStringLocalizer<T> sono stati progettato per migliorare la produttività durante lo sviluppo di app localizzate. IStringLocalizer usa ResourceManager e ResourceReader per fornire risorse specifiche della cultura in fase di esecuzione. L'interfaccia ha un indicizzatore e un oggetto IEnumerable per la restituzione di stringhe localizzate. IStringLocalizer non richiede l'archiviazione delle stringhe di lingua predefinite in un file di risorse. È possibile sviluppare un'app per la localizzazione senza creare file di risorse nelle prime fasi di sviluppo. Il codice seguente illustra come eseguire il wrapping della stringa "About Title" per la localizzazione.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Localization.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get()
        {
            return _localizer["About Title"];
        }
    }
}

Nel codice precedente, l'implementazione di IStringLocalizer<T> proviene dall'Iniezione di Dipendenze. Se non viene trovato il valore localizzato di "About Title", viene restituita la chiave dell'indicizzatore, ovvero la stringa "About Title". È possibile lasciare le stringhe letterali della lingua predefinita nell'app ed eseguirne il wrapping nel localizzatore per potersi concentrare sullo sviluppo dell'app. Sviluppare l'app con la lingua predefinita e prepararla per la fase di localizzazione senza prima creare un file di risorse predefinito. In alternativa, è possibile usare l'approccio tradizionale e fornire una chiave per recuperare la stringa della lingua predefinita. Per molti sviluppatori il nuovo flusso di lavoro che prevede di non avere un file con estensione resx della lingua predefinita e di eseguire semplicemente il wrapping dei valori letterali di stringa consente di ridurre il sovraccarico della localizzazione di un'app. Altri sviluppatori preferiranno il tradizionale flusso di lavoro, poiché può semplificare l'uso di valori letterali di stringa più lunghi e facilitare l'aggiornamento delle stringhe localizzate.

Usare l'implementazione IHtmlLocalizer<T> per le risorse che contengono HTML. L'HTML di IHtmlLocalizer codifica gli argomenti formattati nella stringa di risorsa, ma non codifica in HTML la stringa di risorsa. Nell'esempio evidenziato di seguito, solo il valore del parametro name è codificato in HTML.

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;

namespace Localization.Controllers
{
    public class BookController : Controller
    {
        private readonly IHtmlLocalizer<BookController> _localizer;

        public BookController(IHtmlLocalizer<BookController> localizer)
        {
            _localizer = localizer;
        }

        public IActionResult Hello(string name)
        {
            ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];

            return View();
        }

Note

In genere, localizzare solo il testo, non l'HTML.

Al livello più basso, è possibile ottenere IStringLocalizerFactory dalla Dependency Injection:

{
    public class TestController : Controller
    {
        private readonly IStringLocalizer _localizer;
        private readonly IStringLocalizer _localizer2;

        public TestController(IStringLocalizerFactory factory)
        {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(type);
            _localizer2 = factory.Create("SharedResource", assemblyName.Name);
        }       

        public IActionResult About()
        {
            ViewData["Message"] = _localizer["Your application description page."] 
                + " loc 2: " + _localizer2["Your application description page."];

Il codice precedente illustra ognuno dei due metodi di creazione della factory.

È possibile suddividere le stringhe localizzate per controller o area oppure usare un unico contenitore. Nell'app di esempio, viene usata una classe fittizia denominata SharedResource per le risorse condivise.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Alcuni sviluppatori usano la classe Startup per contenere le stringhe globali o condivise. Nell'esempio seguente vengono usati i localizzatori InfoController e SharedResource:

public class InfoController : Controller
{
    private readonly IStringLocalizer<InfoController> _localizer;
    private readonly IStringLocalizer<SharedResource> _sharedLocalizer;

    public InfoController(IStringLocalizer<InfoController> localizer,
                   IStringLocalizer<SharedResource> sharedLocalizer)
    {
        _localizer = localizer;
        _sharedLocalizer = sharedLocalizer;
    }

    public string TestLoc()
    {
        string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
                     " Info resx " + _localizer["Hello!"];
        return msg;
    }

Visualizzare la localizzazione

Il servizio IViewLocalizer fornisce le stringhe localizzate per una visualizzazione. La classe ViewLocalizer implementa questa interfaccia e individua la posizione della risorsa dal percorso del file della visualizzazione. Il codice seguente illustra come usare l'implementazione predefinita di IViewLocalizer:

@using Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>@Localizer["Use this area to provide additional information."]</p>

L'implementazione predefinita di IViewLocalizer individua il file di risorse in base al nome file della visualizzazione. Non è disponibile alcuna opzione per l'uso di un file di risorse condivise globali. ViewLocalizer implementa il localizzatore usando IHtmlLocalizer, quindi Razor non codifica la stringa localizzata. È possibile parametrizzare le stringhe di risorsa e IViewLocalizer codificherà in HTML i parametri ma non la stringa di risorsa. Considerare il markup seguente Razor :

@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]

Un file di risorse francese può contenere quanto segue:

Key Value
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

La vista renderizzata conterrà il markup HTML del file delle risorse.

Note

In genere, localizzare solo il testo, non l'HTML.

Per usare un file di risorse condivise in una visualizzazione, inserire IHtmlLocalizer<T>:

@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services

@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>

<h1>@SharedLocalizer["Hello!"]</h1>

Localizzazione di DataAnnotations

I messaggi di errore DataAnnotations vengono localizzati con IStringLocalizer<T>. Usando l'opzione ResourcesPath = "Resources" è possibile memorizzare i messaggi di errore in RegisterViewModel in uno dei percorsi seguenti:

  • Resources/ViewModels.Account.RegisterViewModel.fr.resx
  • Resources/ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
    [Required(ErrorMessage = "The Email field is required.")]
    [EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required(ErrorMessage = "The Password field is required.")]
    [StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

Gli attributi di non convalida vengono localizzati.

Uso di un'unica stringa di risorsa per più classi

Il codice seguente illustra come usare una sola stringa di risorsa per gli attributi di convalida con più classi:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddDataAnnotationsLocalization(options => {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });
}

Nel codice precedente SharedResource è la classe corrispondente al file con estensione resx in cui sono memorizzati i messaggi di convalida. Con questo approccio, DataAnnotations userà solo SharedResource anziché la risorsa per ogni classe.

Fornire le risorse localizzate per le lingue e le culture supportate

SupportedCultures e SupportedUICultures

ASP.NET Core consente di specificare due valori di impostazioni cultura, SupportedCultures e SupportedUICultures. L'oggetto CultureInfo per SupportedCultures determina i risultati delle funzioni dipendenti dalla cultura, come la formattazione di data, ora, numero e valuta. SupportedCultures determina anche l'ordinamento del testo, le convenzioni di maiuscole e minuscole e i confronti di stringhe. Per altre informazioni su come il server ottiene le impostazioni cultura, vedere CultureInfo.CurrentCulture e CultureInfo.CurrentUICulture. Determina SupportedUICultures quali stringhe tradotte (da .resx file) vengono cercate da ResourceManager. Cerca ResourceManager stringhe specifiche della cultura determinate da CurrentUICulture. Ogni thread in .NET include oggetti CurrentCulture e CurrentUICulture. Il framework ispeziona questi valori durante il rendering delle funzioni dipendenti dalle impostazioni culturali. Se le impostazioni della cultura del thread corrente sono impostate su en-US (inglese, Stati Uniti), DateTime.Now.ToLongDateString() visualizza Thursday, February 18, 2016; ma se CurrentCulture è impostato su es-ES (spagnolo, Spagna), l'output è jueves, 18 de febrero de 2016.

File di risorse

Un file di risorse è un meccanismo utile per la separazione delle stringhe localizzabili dal codice. Le stringhe tradotte per la lingua non predefinita sono isolate nei file di risorse resx . È possibile ad esempio che si voglia creare un file di risorse spagnolo denominato Welcome.es.resx contenente le stringhe tradotte. "es" è il codice di lingua per lo spagnolo. Per creare questo file di risorse in Visual Studio:

  1. In Esplora soluzioni, fare clic con il pulsante destro del mouse sulla cartella che conterrà il file delle risorse e selezionare Aggiungi>Nuovo elemento.

    Menu contestuale annidato: in Esplora soluzioni è aperto un menu contestuale per Risorse. Un secondo menu contestuale è aperto per Aggiungi che mostra il comando Nuovo elemento evidenziato.

  2. Nella casella Cerca modelli installati immettere "risorse" e assegnare un nome al file.

    Finestra di dialogo Aggiungi nuovo elemento

  3. Immettere il valore della chiave (stringa nativa) nella colonna Nome e la stringa tradotta nella colonna Valore.

    File Welcome.es.resx (file di risorse Welcome per lo spagnolo) con la parola Hello nella colonna Nome e la parola Hola nella colonna Valore

    Visual Studio visualizza il file Welcome.es.resx.

    Esplora soluzioni con il file di risorse Welcome per lo spagnolo (es)

Denominazione dei file di risorse

Le risorse sono denominate con il nome completo del tipo della relativa classe meno il nome dell'assembly. Ad esempio, una risorsa francese di un progetto il cui assembly principale è LocalizationWebsite.Web.dll per la classe LocalizationWebsite.Web.Startup viene denominata Startup.fr.resx. Una risorsa per la classe LocalizationWebsite.Web.Controllers.HomeController viene denominata Controllers.HomeController.fr.resx. Se lo spazio dei nomi della classe di destinazione non corrisponde al nome dell'assembly è necessario specificare il nome completo del tipo. Ad esempio, nel progetto di esempio una risorsa per il tipo ExtraNamespace.Tools verrebbe denominata ExtraNamespace.Tools.fr.resx.

Nel progetto di esempio il metodo ConfigureServices imposta il ResourcesPath su "Resources", quindi il percorso relativo del progetto per il file di risorse francese del controller home è Resources/Controllers.HomeController.fr.resx. In alternativa, è possibile usare le cartelle per organizzare i file di risorse. Per il controller home, il percorso sarà Resources/Controllers/HomeController.fr.resx. Se non si usa l'opzione ResourcesPath, il file con estensione resx viene memorizzato nella directory di base del progetto. Il file di risorse per HomeController sarà denominato Controllers.HomeController.fr.resx. La scelta di usare la convenzione di denominazione con punti o percorsi dipende da come si desidera organizzare i file di risorse.

Nome risorsa Denominazione a punto o di percorso
Resources/Controllers.HomeController.fr.resx Dot
Resources/Controllers/HomeController.fr.resx Path

I file di risorse che usano @inject IViewLocalizer nelle Razor visualizzazioni seguono un modello simile. Un file di risorse per una visualizzazione può essere denominato utilizzando la nomenclatura a punti o quella per percorsi. Razor i file di risorse replicano il percorso del loro file di visualizzazione associato. Supponendo di impostare ResourcesPath su "Resources", il file di risorse francese associato alla vista Views/Home/About.cshtml potrebbe essere uno dei seguenti file:

  • Resources/Views/Home/About.fr.resx

  • Resources/Views.Home. About.fr.resx

Se non si usa l'opzione ResourcesPath, il file con estensione resx per una visualizzazione viene inserito nella stessa cartella della visualizzazione.

RootNamespaceAttribute

L'attributo RootNamespaceAttribute fornisce lo spazio dei nomi radice di un assembly quando lo spazio dei nomi radice di un assembly è diverso dal nome dell'assembly.

Warning

Ciò può verificarsi quando il nome di un progetto non è un identificatore .NET valido. Ad esempio my-project-name.csproj , userà lo spazio dei nomi my_project_name radice e il nome my-project-name dell'assembly che genera questo errore.

Se il namespace radice di un assembly è differente dal nome dell'assembly:

  • Per impostazione predefinita, la localizzazione non funziona.
  • La localizzazione fallisce a causa del modo in cui le risorse vengono cercate all'interno dell'assembly. RootNamespace è un valore necessario in fase di compilazione che non è disponibile per il processo in esecuzione.

Se è RootNamespace diverso da AssemblyName, includere quanto segue in AssemblyInfo.cs (con i valori dei parametri sostituiti con i valori effettivi):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

Il codice precedente consente di risolvere correttamente i file resx.

Comportamento di fallback delle impostazioni di cultura

Durante la ricerca di una risorsa, la localizzazione esegue un "fallback culturale". A partire dalla cultura richiesta, se non trovata, si ritorna alla cultura principale di quella richiesta. Per inciso, la proprietà CultureInfo.Parent rappresenta la cultura di origine. Ciò comporta in genere (ma non sempre) la rimozione della notazione nazionale dal codice ISO. Ad esempio la versione della lingua spagnola parlata in Messico è "es-MX". Ha come genitore "es" - spagnolo non specifico per alcun paese.

Si supponga che il sito riceva una richiesta per una risorsa "Welcome" utilizzando la cultura "fr-CA". Il sistema di localizzazione cerca le risorse seguenti nell'ordine elencato e seleziona la prima corrispondenza:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx (se NeutralResourcesLanguage è "fr-CA")

Ad esempio, se si rimuove l'indicatore delle impostazioni cultura ".fr" e le impostazioni cultura sono impostate sul francese, viene letto il file di risorse predefinito e vengono localizzate le stringhe. Il gestore delle risorse assegna una risorsa predefinita o di fallback per i casi in cui nessun elemento soddisfa la cultura richiesta. Per restituire solo la chiave in caso di mancanza di una risorsa per la cultura richiesta, non deve esistere un file di risorse predefinito.

Generare file di risorse con Visual Studio

Se crei un file delle risorse in Visual Studio senza una cultura specificata nel nome del file (ad esempio, Welcome.resx), Visual Studio creerà una classe C# con una proprietà per ogni stringa. In genere questo non è il risultato desiderato quando si usa ASP.NET Core. Solitamente non è presente un file di risorse con estensione resx predefinito (un file con estensione resx senza nome delle impostazioni cultura). È consigliato creare il file con estensione .resx con un nome cultura, ad esempio Welcome.fr.resx. Quando si crea un file .resx con un nome cultura, Visual Studio non genera il file di classe.

Aggiungere altre culture

Ogni combinazione di lingua e impostazioni cultura (diversa dalla lingua predefinita) richiede un file di risorse univoco. È possibile creare file di risorse per le impostazioni cultura e locali diverse creando nuovi file di risorse in cui i codici di lingua ISO sono inclusi nel nome del file, ad esempio en-us, fr-ca e en-gb. I codici ISO vengono inseriti tra il nome file e l'estensione resx come in Welcome.es-MX.resx (spagnolo/Messico).

Implementare una strategia per la selezione della lingua/cultura per ogni richiesta

Configurare la localizzazione

La localizzazione è configurata nel metodo Startup.ConfigureServices:

services.AddLocalization(options => options.ResourcesPath = "Resources");

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization aggiunge i servizi di localizzazione al contenitore dei servizi. Il codice precedente imposta anche il percorso delle risorse su "Resources".

  • AddViewLocalization aggiunge il supporto per i file di visualizzazione localizzati. Nell'esempio la localizzazione delle visualizzazioni è basata sul suffisso dei file di visualizzazione. Ad esempio , "fr" nel Index.fr.cshtml file .

  • AddDataAnnotationsLocalization aggiunge il supporto per i messaggi di convalida localizzati DataAnnotations tramite IStringLocalizer astrazioni.

Middleware di localizzazione

La cultura corrente su una richiesta è impostata nel Middleware di localizzazione. Il middleware di localizzazione viene abilitato nel metodo Startup.Configure. Il middleware di localizzazione deve essere configurato prima di qualsiasi middleware che possa controllare la cultura richiesta della richiesta, ad esempio app.UseMvcWithDefaultRoute(). Il middleware di localizzazione deve essere visualizzato dopo il middleware di routing se si usa RouteDataRequestCultureProvider. Per ulteriori informazioni sull'ordine del middleware, vedere ASP.NET Core Middleware.

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

app.UseRequestLocalization(localizationOptions);

UseRequestLocalization inizializza un oggetto RequestLocalizationOptions. L'elenco di RequestCultureProvider in RequestLocalizationOptions viene enumerato ad ogni richiesta e viene usato il primo provider in grado di determinare la cultura della richiesta. I provider predefiniti provengono dalla classe RequestLocalizationOptions:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

L'elenco predefinito passa dal più specifico al meno specifico. In seguito in questo articolo vedremo come modificare l'ordine e persino aggiungere un provider delle impostazioni cultura personalizzato. Se nessuno dei provider è in grado di determinare la cultura della richiesta, viene usato DefaultRequestCulture.

QueryStringRequestCultureProvider

Alcune app useranno una stringa di query per impostare il CultureInfo. Per le app che usano l'approccio di intestazione cookie o Accept-Language, aggiungere una stringa di query all'URL è utile per il debug e il test del codice. Per impostazione predefinita, QueryStringRequestCultureProvider viene registrato come primo provider di localizzazione nell'elenco RequestCultureProvider. Passare i parametri della stringa di query culture e ui-culture. L'esempio seguente specifica le impostazioni cultura specifiche (lingua e area) per spagnolo/Messico:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Se si passa uno solo dei due parametri (culture o ui-culture), il provider della stringa di query imposterà entrambi i valori usando il parametro passato. Ad esempio, se si specificano solo le impostazioni cultura verranno impostati entrambi i parametri Culture e UICulture:

http://localhost:5000/?culture=es-MX

CookieRequestCultureProvider

Le app di produzione forniscono spesso un meccanismo per impostare la cultura con la cultura di ASP.NET Core cookie. Usare il MakeCookieValue metodo per creare un oggetto cookie.

Viene restituito CookieRequestCultureProviderDefaultCookieName il nome predefinito cookie utilizzato per tenere traccia delle informazioni sulla cultura preferita dell'utente. Il nome predefinito cookie è .AspNetCore.Culture.

Il formato cookie è c=%LANGCODE%|uic=%LANGCODE%, dove c è Culture e uic è UICulture, ad esempio:

c=en-UK|uic=en-US

Se si specificano solo le informazioni cultura oppure le informazioni cultura dell'interfaccia utente, le informazioni specificate verranno usate per entrambe le impostazioni.

Intestazione Accept-Language HTTP

L'intestazione Accept-Language può essere impostata nella maggior parte dei browser ed è stata originariamente progettata per specificare la lingua dell'utente. Questa impostazione indica cosa è stato impostato per l'invio da parte del browser o cosa è stato ereditato dal sistema operativo sottostante. L'intestazione HTTP Accept-Language di una richiesta del browser non è un metodo infallibile per individuare la lingua preferita dell'utente (vedere Setting language preferences in a browser (Impostazione delle preferenze di lingua in un browser)). Un'app di produzione deve consentire all'utente di personalizzare le impostazioni culturali.

Impostare l'intestazione HTTP Accept-Language in IE

  1. Dall'icona a forma di ingranaggio, toccare Opzioni Internet.

  2. Toccare Lingue.

    Opzioni Internet

  3. Toccare Imposta preferenze lingua.

  4. Toccare Aggiungi una lingua.

  5. Aggiungere la lingua.

  6. Tocca la lingua, poi tocca Sposta su.

Usare un provider personalizzato

Si supponga di voler consentire ai clienti di memorizzare la loro lingua e cultura nei database. È possibile creare un provider per la ricerca di questi valori per l'utente. Il codice seguente illustra come aggiungere un provider personalizzato:

private const string enUSCulture = "en-US";

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo(enUSCulture),
        new CultureInfo("fr")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return await Task.FromResult(new ProviderCultureResult("en"));
    }));
});

Usare RequestLocalizationOptions per aggiungere o rimuovere i provider di localizzazione.

Modificare l'ordine dei provider di impostazioni cultura della richiesta

RequestLocalizationOptions ha tre provider di impostazioni cultura delle richieste predefinite: QueryStringRequestCultureProvider, CookieRequestCultureProvidere AcceptLanguageHeaderRequestCultureProvider. Utilizzare la proprietà [RequestLocalizationOptions.RequestCultureProviders]](xref:Microsoft.AspNetCore.Builder.RequestLocalizationOptions.RequestCultureProviders) per modificare l'ordine di questi provider, come illustrato di seguito:

    app.UseRequestLocalization(options =>
    {
        var questStringCultureProvider = options.RequestCultureProviders[0];    
        options.RequestCultureProviders.RemoveAt(0);
        options.RequestCultureProviders.Insert(1, questStringCultureProvider);
    });

Nell'esempio precedente, l'ordine di QueryStringRequestCultureProvider e CookieRequestCultureProvider viene modificato, quindi RequestLocalizationMiddleware cerca prima le culture impostate dai cookie e poi le stringhe di query.

Come accennato in precedenza, aggiungere un provider personalizzato tramite AddInitialRequestCultureProvider il quale imposta l'ordine su 0, quindi questo provider ha la precedenza sugli altri.

Impostare le impostazioni culturali programmaticamente

Questo progetto di esempio Localization.StarterWeb in GitHub contiene l'interfaccia utente per impostare Culture. Il Views/Shared/_SelectLanguagePartial.cshtml file consente di selezionare la cultura dall'elenco delle culture supportate.

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home" 
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" 
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
          onchange="this.form.submit();"
          asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
        </select>
    </form>
</div>

Il Views/Shared/_SelectLanguagePartial.cshtml file viene aggiunto alla footer sezione del file di layout in modo che sia disponibile per tutte le visualizzazioni:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

Il SetLanguage metodo imposta la cultura cookie.

[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
        new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
    );

    return LocalRedirect(returnUrl);
}

Non è possibile collegare l'oggetto _SelectLanguagePartial.cshtml al codice d'esempio di questo progetto. Il progetto Localization.StarterWeb in GitHub include codice per passare RequestLocalizationOptions a un Razor oggetto parziale tramite il contenitore Dependency Injection .

Associazione di modelli con i dati di route e le stringhe di query

Vedere Comportamento della globalizzazione dei dati di route e delle stringhe di query nell'associazione dei modelli.

Termini relativi alla globalizzazione e alla localizzazione

Il processo di localizzazione dell'app richiede anche una conoscenza di base dei set di caratteri comunemente usati nello sviluppo del software moderno e dei problemi associati a essi. Sebbene tutti i computer memorizzano il testo come numeri (codici), sistemi diversi memorizzano lo stesso testo usando numeri diversi. Il processo di localizzazione si riferisce alla traduzione dell'interfaccia utente dell'app per impostazioni cultura o locali specifiche.

La localizzabilità è un processo intermedio che verifica che un'app globalizzata sia pronta per la localizzazione.

Il formato RFC 4646 per il nome cultura è <languagecode2>-<country/regioncode2>, dove <languagecode2> è il codice della lingua e <country/regioncode2> è il codice della subcultura. Ad esempio, es-CL per spagnolo (Cile), en-US per inglese (Stati Uniti) e en-AU per inglese (Australia). RFC 4646 è la combinazione di un codice di cultura in lettere minuscole di due lettere ISO 639 associato a una lingua e un codice di cultura secondaria in lettere maiuscole di due lettere ISO 3166 associato a un paese o un'area. Per ulteriori informazioni, vedere System.Globalization.CultureInfo.

L'internazionalizzazione è spesso abbreviata con "I18N". L'abbreviazione utilizza la prima e l'ultima lettera del termine, più il numero di lettere tra di esse. Per esempio, 18 rappresenta il numero di lettere tra la prima "I" e l'ultima "N". Lo stesso vale per globalizzazione (G11N) e localizzazione (L10N).

Terms:

  • Globalizzazione (G11N): processo che consente a un'app di supportare lingue e aree diverse.
  • Localizzazione (L10N): processo di personalizzazione di un'app per una determinata lingua e area.
  • Internazionalizzazione (I18N): descrive la globalizzazione e la localizzazione.
  • La cultura: è una lingua e, facoltativamente, una regione.
  • Cultura neutra: Una cultura che ha una lingua specificata, ma senza una regione. (ad esempio "en", "es")
  • Cultura specifica: una cultura che ha una lingua e una regione specificata. (ad esempio "en-US", "en-GB", "es-CL")
  • Cultura padre: La cultura neutra che contiene una cultura specifica. (ad esempio, "en" rappresenta la cultura principale di "en-US" e "en-GB")
  • Locale: Un locale è lo stesso di una cultura.

Note

Potresti non essere in grado di immettere virgole decimali nei campi decimali. Per supportare la convalida jQuery per impostazioni locali diverse dall'inglese che usano la virgola (",") come separatore decimale e per formati di data diversi da quello dell'inglese degli Stati Uniti, è necessario eseguire alcuni passaggi per globalizzare l'app. Per istruzioni sull'aggiunta di una virgola decimale, vedere questo commento di GitHub 4076 .

Note

Prima dell'introduzione di ASP.NET Core 3.0, le applicazioni web scrivevano un log di tipo LogLevel.Warning per ogni richiesta se le impostazioni culturali richieste non erano supportate. La registrazione di una LogLevel.Warning per ogni richiesta può generare file di log di grandi dimensioni con informazioni ridondanti. Questo comportamento è stato modificato in ASP.NET Core 3.0. Scrive RequestLocalizationMiddleware un log di tipo LogLevel.Debug, che riduce le dimensioni dei log di produzione.

Risorse aggiuntive