Globalizzazione e localizzazione in ASP.NET Core

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.
  • Impostazioni cultura: lingua e, facoltativamente, un'area.
  • Impostazioni cultura neutre: impostazioni cultura con una lingua specificata, ma non un'area (ad esempio "en", "es").
  • Impostazioni cultura specifiche: impostazioni cultura con una lingua e un'area specificate(ad esempio, "en-US", "en-GB", "es-CL").
  • Impostazioni cultura padre: le impostazioni cultura neutre che contengono impostazioni cultura specifiche, ad esempio "en" sono le impostazioni cultura padre di "en-US" e "en-GB".
  • Impostazioni locali: le impostazioni locali corrispondono alle impostazioni cultura.

Codici lingua e paese/area geografica

Il formato RFC 4646 per il nome delle impostazioni cultura è <language code>-<country/region code>, dove <language code> identifica la lingua e <country/region code> identifica la sottoculture. 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.
  • Impostazioni cultura: lingua e, facoltativamente, un'area.
  • Impostazioni cultura neutre: impostazioni cultura con una lingua specificata, ma non un'area (ad esempio "en", "es").
  • Impostazioni cultura specifiche: impostazioni cultura con una lingua e un'area specificate(ad esempio, "en-US", "en-GB", "es-CL").
  • Impostazioni cultura padre: le impostazioni cultura neutre che contengono impostazioni cultura specifiche, ad esempio "en" sono le impostazioni cultura padre di "en-US" e "en-GB".
  • Impostazioni locali: le impostazioni locali corrispondono alle impostazioni cultura.

Codici lingua e paese/area geografica

Il formato RFC 4646 per il nome delle impostazioni cultura è <language code>-<country/region code>, dove <language code> identifica la lingua e <country/region code> identifica la sottoculture. 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 impostazioni cultura 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 la localizzazione, a particolari impostazioni cultura e impostazioni locali. 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 impostazioni cultura supportate
  3. Implementare una strategia per la selezione della lingua o delle impostazioni 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 e ResourceManagerResourceReader per fornire risorse specifiche delle impostazioni 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 deriva dall'inserimento IStringLocalizer<T>delle 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 preferiscono il flusso di lavoro tradizionale poiché semplifica l'uso di valori letterali di stringa più lunghi e 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();
        }

Nota

In genere, solo localizzare il testo, non HTML.

Al livello più basso, è possibile ottenere IStringLocalizerFactory dall'inserimento delle dipendenze:

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

Localizzazione delle visualizzazioni

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:

Chiave valore
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

La visualizzazione di cui è stato eseguito il rendering conterrà il markup HTML del file di risorse.

Nota

In genere, solo localizzare il testo, non 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 impostazioni cultura 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 dalle impostazioni cultura, ad esempio data, ora, numero e formattazione della 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 delle impostazioni cultura determinate da CurrentUICulture. Ogni thread in .NET include oggetti CurrentCulture e CurrentUICulture. Il framework controlla questi valori durante il rendering delle funzioni dipendenti dalle impostazioni cultura. Se le impostazioni cultura del thread corrente sono impostate su (inglese, Stati Uniti), visualizza Thursday, February 18, 2016; ma se CurrentCulture è impostato en-US su es-ES (spagnolo, Spagna), DateTime.Now.ToLongDateString() 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 >di risorse Aggiungi>nuovo elemento.

    Nested contextual menu: In Solution Explorer, a contextual menu is open for Resources. A second contextual menu is open for Add showing the New Item command highlighted.

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

    Add New Item dialog

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

    Welcome.es.resx file (the Welcome resource file for Spanish) with the word Hello in the Name column and the word Hola (Hello in Spanish) in the Value column

    Visual Studio visualizza il file Welcome.es.resx.

    Solution Explorer showing the Welcome Spanish (es) resource file

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 sarà 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 ConfigureServices metodo imposta su ResourcesPath "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 principale, 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 sarebbe denominato Controllers.HomeController.fr.resx. La scelta di usare la convenzione di denominazione con il punto o il percorso dipende da come si vuole organizzare i file di risorse.

Nome risorsa Denominazione con il punto o il percorso
Risorse/controller.HomeController.fr.resx Punto
Resources/Controllers/HomeController.fr.resx Percorso

I file di risorse che usano @inject IViewLocalizer nelle Razor visualizzazioni seguono un modello simile. Il file di risorse per una visualizzazione può essere denominato usando la denominazione con il punto o con il percorso. Razor visualizzare i file di risorse simulare il percorso del file di visualizzazione associato. Supponendo di impostare su ResourcesPath "Resources", il file di risorse francese associato alla Views/Home/About.cshtml vista potrebbe essere uno dei seguenti:

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

Avviso

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 lo spazio dei nomi radice di un assembly è diverso dal nome dell'assembly:

  • Per impostazione predefinita, la localizzazione non funziona.
  • Le risorse vengono cercate all'interno dell'assembly in un modo che impedisce la localizzazione. 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 cultura

Durante la ricerca di una risorsa, la localizzazione esegue un "fallback delle impostazioni cultura". A partire dalle impostazioni cultura richieste, se queste non vengono trovate, il codice adotta le impostazioni cultura padre di quelle richieste. Da parte, la CultureInfo.Parent proprietà rappresenta le impostazioni cultura padre. 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 il padre "es" - spagnolo non specifico di qualsiasi paese.

Si supponga che il sito riceva una richiesta di una risorsa "Welcome" che usa le impostazioni 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. Lo strumento di gestione delle risorse imposta una risorsa predefinita o di fallback per i casi in cui nessun elemento soddisfa le impostazioni cultura richieste. Per restituire solo la chiave in caso di mancanza di una risorsa per le impostazioni cultura richieste è necessario che non sia specificato un file di risorse predefinito.

Generare file di risorse con Visual Studio

Se si crea un file di risorse in Visual Studio senza le impostazioni cultura nel nome del file (ad esempio, Welcome.resx), Visual Studio crea 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). Si consiglia di creare il file con estensione resx con un nome delle impostazioni cultura, ad esempio Welcome.fr.resx. Quando si crea un file con estensione resx con un nome delle impostazioni cultura, Visual Studio non genera il file di classe.

Aggiungere altre impostazioni cultura

Ogni combinazione di lingua e impostazioni cultura (diversa dalla lingua predefinita) richiede un file di risorse univoco. Creare file di risorse per impostazioni cultura e locali diverse creando nuovi file di risorse in cui i codici di lingua ISO sono inclusi nel nome 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 o delle impostazioni 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

Le impostazioni cultura correnti in un richiesta sono impostate 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 le impostazioni cultura della richiesta , ad esempio app.UseMvcWithDefaultRoute(). Il middleware di localizzazione deve essere visualizzato dopo il middleware di routing se si usa RouteDataRequestCultureProvider. Per altre informazioni sull'ordine del middleware, vedere ASP.NET Middleware core.

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

app.UseRequestLocalization(localizationOptions);

Per visualizzare i commenti del codice tradotti in lingue diverse dall'inglese, segnalarlo in questo problema di discussione su GitHub.

UseRequestLocalization inizializza un oggetto RequestLocalizationOptions. In ogni richiesta l'elenco di RequestCultureProvider in RequestLocalizationOptions è enumerato e viene usato il primo provider in grado di determinare le impostazioni 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. Di seguito in questo articolo viene descritto come modificare l'ordine e aggiungere un provider delle impostazioni cultura personalizzato. Se nessuno dei provider è in grado di determinare le impostazioni cultura della richiesta, viene usato DefaultRequestCulture.

QueryStringRequestCultureProvider

Alcune app useranno una stringa di query per impostare .CultureInfo Per le app che usano l'approccio cookie di intestazione o Accept-Language, l'aggiunta di 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 le impostazioni cultura con le impostazioni cultura cookiedi base ASP.NET . Usare il MakeCookieValue metodo per creare un oggetto cookie.

Restituisce CookieRequestCultureProviderDefaultCookieName il nome predefinito cookie utilizzato per tenere traccia delle informazioni sulle impostazioni cultura preferite dell'utente. Il nome predefinito cookie è .AspNetCore.Culture.

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

c=en-UK|uic=en-US

Se si specificano solo le impostazioni cultura o le impostazioni cultura dell'interfaccia utente, le impostazioni specificate verranno usate per entrambi i tipi di impostazioni.

Intestazione HTTP Accept-Language

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 la lingua impostata per l'invio da parte del browser o che il browser ha 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 cultura.

Impostare l'intestazione HTTP Accept-Language in IE

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

  2. Toccare Lingue.

    Internet Options

  3. Toccare Imposta preferenze lingua.

  4. Toccare Aggiungi una lingua.

  5. Aggiungere la lingua.

  6. Toccare la lingua e quindi toccare Sposta su.

Usare un provider personalizzato

Si supponga di voler consentire agli utenti di memorizzare lingua e impostazioni 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 le impostazioni cultura dalla cookieprima, quindi la stringa 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.

Specificare le impostazioni cultura a livello di codice

Questo progetto di esempio Localization.StarterWeb in GitHub contiene l'interfaccia utente per impostare Culture. Il Views/Shared/_SelectLanguagePartial.cshtml file consente di selezionare le impostazioni cultura dall'elenco delle impostazioni cultura 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 le impostazioni 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 di esempio per questo progetto. Il progetto Localization.StarterWeb in GitHub include codice per passare RequestLocalizationOptions a un Razor oggetto parziale tramite il contenitore Dependency Injection .

Dati di route di associazione di modelli e stringhe di query

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

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 delle impostazioni cultura è <languagecode2>-<country/regioncode2>, dove <languagecode2> è il codice della lingua e <country/regioncode2> è il codice della cultura secondaria. 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 include la prima e l'ultima lettera e il numero di lettere che intercorrono tra di loro nel termine inglese "Internationalization". 18 è il numero di lettere tra la prima "I" e l'ultima "N". Lo stesso vale per globalizzazione (G11N) e localizzazione (L10N).

Termini:

  • 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.
  • Impostazioni cultura: si tratta di una lingua e, facoltativamente, di un'area.
  • Impostazioni cultura neutre: cultura con una lingua specificata ma senza area. (ad esempio "en", "es")
  • Impostazioni cultura specifiche: cultura con una lingua e un'area specificate. (ad esempio "en-US", "en-GB", "es-CL")
  • Impostazioni padre: impostazioni cultura neutre con impostazioni cultura specifiche. (ad esempio, "en" rappresenta le impostazioni cultura padre di "en-US" e "en-GB")
  • Impostazioni locali: le impostazioni locali corrispondono alle impostazioni cultura.

Nota

È possibile che non si riesca a immettere virgole decimali nel campo. 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 .

Nota

Prima di ASP.NET le app Web Core 3.0 scrivono un log di tipo LogLevel.Warning per richiesta se le impostazioni cultura richieste non sono supportate. La registrazione di una LogLevel.Warning per richiesta può creare file di log di grandi dimensioni con informazioni ridondanti. Questo comportamento è stato modificato in ASP.NET 3.0. Scrive RequestLocalizationMiddleware un log di tipo LogLevel.Debug, che riduce le dimensioni dei log di produzione.

Risorse aggiuntive