Globalizzazione e localizzazione in ASP.NET CoreGlobalization and localization in ASP.NET Core

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

La creazione di un sito Web multilingue con ASP.NET Core consente al sito di raggiungere un pubblico più ampio.Creating a multilingual website with ASP.NET Core will allow your site to reach a wider audience. AP.NET Core offre servizi e middleware per la localizzazione in diverse lingue e culture.ASP.NET Core provides services and middleware for localizing into different languages and cultures.

L'internazionalizzazione implica la globalizzazione e la localizzazione.Internationalization involves Globalization and Localization. La globalizzazione è il processo di progettazione di app che supportano impostazioni cultura diverse.Globalization is the process of designing apps that support different cultures. 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.Globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas.

La localizzazione è il processo di adattamento di un'app globalizzata, già elaborata per la localizzazione, a particolari impostazioni cultura e impostazioni locali.Localization is the process of adapting a globalized app, which you have already processed for localizability, to a particular culture/locale. Per altre informazioni, vedere Termini relativi alla globalizzazione e alla localizzazione nella parte finale di questo documento.For more information see Globalization and localization terms near the end of this document.

La localizzazione dell'app comporta quanto segue:App localization involves the following:

  1. Rendere localizzabile il contenuto dell'appMake the app's content localizable

  2. Fornire le risorse localizzate per le lingue e le impostazioni cultura supportateProvide localized resources for the languages and cultures you support

  3. Implementare una strategia per la selezione della lingua o delle impostazioni cultura per ogni richiestaImplement a strategy to select the language/culture for each request

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

Rendere localizzabile il contenuto dell'appMake the app's content localizable

Introdotte in ASP.NET Core, IStringLocalizer e IStringLocalizer<T> sono state progettate per migliorare la produttività durante lo sviluppo di app localizzate.Introduced in ASP.NET Core, IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer usa ResourceManager e ResourceReader per fornire le risorse specifiche delle impostazioni cultura durante il runtime.IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time. L'interfaccia semplice include un indicizzatore e IEnumerable per la restituzione di stringhe localizzate.The simple interface has an indexer and an IEnumerable for returning localized strings. IStringLocalizer non richiede di memorizzare le stringhe della lingua predefinita in un file di risorse.IStringLocalizer doesn't require you to store the default language strings in a resource file. È possibile sviluppare un'app per la localizzazione senza creare file di risorse nelle prime fasi di sviluppo.You can develop an app targeted for localization and not need to create resource files early in development. Il codice seguente illustra come eseguire il wrapping della stringa "About Title" per la localizzazione.The code below shows how to wrap the string "About Title" for localization.

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 l'implementazione IStringLocalizer<T> proviene dall'inserimento delle dipendenze.In the code above, the IStringLocalizer<T> implementation comes from Dependency Injection. Se non viene trovato il valore localizzato di "About Title", viene restituita la chiave dell'indicizzatore, ovvero la stringa "About Title".If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "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.You can leave the default language literal strings in the app and wrap them in the localizer, so that you can focus on developing the app. Sviluppare l'app con la lingua predefinita e prepararla per la fase di localizzazione senza prima creare un file di risorse predefinito.You develop your app with your default language and prepare it for the localization step without first creating a default resource file. In alternativa, è possibile usare l'approccio tradizionale e fornire una chiave per recuperare la stringa della lingua predefinita.Alternatively, you can use the traditional approach and provide a key to retrieve the default language string. 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.For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an 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.Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.

Usare l'implementazione IHtmlLocalizer<T> per le risorse che contengono HTML.Use the IHtmlLocalizer<T> implementation for resources that contain HTML. L'HTML di IHtmlLocalizer codifica gli argomenti formattati nella stringa di risorsa, ma non codifica in HTML la stringa di risorsa.IHtmlLocalizer HTML encodes arguments that are formatted in the resource string, but doesn't HTML encode the resource string itself. Nell'esempio evidenziato di seguito, solo il valore del parametro name è codificato in HTML.In the sample highlighted below, only the value of name parameter is HTML encoded.

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 si vuole localizzare solo testo e non il codice HTML.Note: You generally want to only localize text and not HTML.

Al livello più basso, è possibile ottenere IStringLocalizerFactory dall'inserimento delle dipendenze:At the lowest level, you can get IStringLocalizerFactory out of 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.The code above demonstrates each of the two factory create methods.

È possibile suddividere le stringhe localizzate per controller o area oppure usare un unico contenitore.You can partition your localized strings by controller, area, or have just one container. Nell'app di esempio, viene usata una classe fittizia denominata SharedResource per le risorse condivise.In the sample app, a dummy class named SharedResource is used for shared resources.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Alcuni sviluppatori usano la classe Startup per contenere le stringhe globali o condivise.Some developers use the Startup class to contain global or shared strings. Nell'esempio seguente vengono usati i localizzatori InfoController e SharedResource:In the sample below, the InfoController and the SharedResource localizers are used:

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 visualizzazioniView localization

Il servizio IViewLocalizer fornisce le stringhe localizzate per una visualizzazione.The IViewLocalizer service provides localized strings for a view. La classe ViewLocalizer implementa questa interfaccia e individua la posizione della risorsa dal percorso del file della visualizzazione.The ViewLocalizer class implements this interface and finds the resource location from the view file path. Il codice seguente illustra come usare l'implementazione predefinita di IViewLocalizer:The following code shows how to use the default implementation of 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.The default implementation of IViewLocalizer finds the resource file based on the view's file name. Non è disponibile alcuna opzione per l'uso di un file di risorse condivise globali.There's no option to use a global shared resource file. Poiché ViewLocalizer implementa il localizzatore usando IHtmlLocalizer, Razor non codifica in HTML la stringa localizzata.ViewLocalizer implements the localizer using IHtmlLocalizer, so Razor doesn't HTML encode the localized string. È possibile parametrizzare le stringhe di risorsa e IViewLocalizer codificherà in HTML i parametri ma non la stringa di risorsa.You can parameterize resource strings and IViewLocalizer will HTML encode the parameters, but not the resource string. Si consideri il markup Razor seguente:Consider the following Razor markup:

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

Un file di risorse francese può contenere quanto segue:A French resource file could contain the following:

ChiaveKey ValueValue
<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.The rendered view would contain the HTML markup from the resource file.

Nota: in genere si vuole localizzare solo testo e non il codice HTML.Note: You generally want to only localize text and not HTML.

Per usare un file di risorse condivise in una visualizzazione, inserire IHtmlLocalizer<T>:To use a shared resource file in a view, inject 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 DataAnnotationsDataAnnotations localization

I messaggi di errore DataAnnotations vengono localizzati con IStringLocalizer<T>.DataAnnotations error messages are localized with IStringLocalizer<T>. Usando l'opzione ResourcesPath = "Resources" è possibile memorizzare i messaggi di errore in RegisterViewModel in uno dei percorsi seguenti:Using the option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in either of the following paths:

  • Resources/ViewModels.Account.RegisterViewModel.fr.resxResources/ViewModels.Account.RegisterViewModel.fr.resx
  • Resources/ViewModels/Account/RegisterViewModel.fr.resxResources/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; }
}

In ASP.NET Core MVC 1.1.0 e versioni successive, gli attributi non di convalida vengono localizzati.In ASP.NET Core MVC 1.1.0 and higher, non-validation attributes are localized. ASP.NET Core MVC 1.0 non ricerca le stringhe localizzate per gli attributi non di convalida.ASP.NET Core MVC 1.0 does not look up localized strings for non-validation attributes.

Uso di un'unica stringa di risorsa per più classiUsing one resource string for multiple classes

Il codice seguente illustra come usare una sola stringa di risorsa per gli attributi di convalida con più classi:The following code shows how to use one resource string for validation attributes with multiple classes:

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.In the preceding code, SharedResource is the class corresponding to the resx where your validation messages are stored. Con questo approccio, DataAnnotations userà solo SharedResource anziché la risorsa per ogni classe.With this approach, DataAnnotations will only use SharedResource, rather than the resource for each class.

Fornire le risorse localizzate per le lingue e le impostazioni cultura supportateProvide localized resources for the languages and cultures you support

SupportedCultures e SupportedUICulturesSupportedCultures and SupportedUICultures

ASP.NET Core consente di specificare due valori di impostazioni cultura, SupportedCultures e SupportedUICultures.ASP.NET Core allows you to specify two culture values, SupportedCultures and SupportedUICultures. L'oggetto CultureInfo per SupportedCultures determina i risultati delle funzioni dipendenti dalle impostazioni cultura, ad esempio date, ore, numeri e formattazione delle valute.The CultureInfo object for SupportedCultures determines the results of culture-dependent functions, such as date, time, number, and currency formatting. SupportedCultures determina anche l'ordinamento del testo, le convenzioni di maiuscole e minuscole e i confronti di stringhe.SupportedCultures also determines the sorting order of text, casing conventions, and string comparisons. Per altre informazioni su come il server ottiene le impostazioni cultura, vedere CultureInfo.CurrentCulture.See CultureInfo.CurrentCulture for more info on how the server gets the Culture. SupportedUICultures determina le stringhe tradotte (dai file con estensione resx) cercate da ResourceManager.The SupportedUICultures determines which translates strings (from .resx files) are looked up by the ResourceManager. ResourceManager esegue la ricerca nelle stringhe specifiche delle impostazioni cultura determinate da CurrentUICulture.The ResourceManager simply looks up culture-specific strings that's determined by CurrentUICulture. Ogni thread in .NET include oggetti CurrentCulture e CurrentUICulture.Every thread in .NET has CurrentCulture and CurrentUICulture objects. ASP.NET Core controlla questi valori quando viene eseguito il rendering delle funzioni dipendenti dalle impostazioni cultura.ASP.NET Core inspects these values when rendering culture-dependent functions. Ad esempio, se le impostazioni cultura del thread corrente sono impostate su "en-US" (inglese, Stati Uniti), DateTime.Now.ToLongDateString() visualizza "Thursday, February 18, 2016". Se invece CurrentCulture è impostato su "es-ES" (spagnolo, Spagna) l'output sarà "jueves, 18 de febrero de 2016".For example, if the current thread's culture is set to "en-US" (English, United States), DateTime.Now.ToLongDateString() displays "Thursday, February 18, 2016", but if CurrentCulture is set to "es-ES" (Spanish, Spain) the output will be "jueves, 18 de febrero de 2016".

File di risorseResource files

Un file di risorse è un meccanismo utile per la separazione delle stringhe localizzabili dal codice.A resource file is a useful mechanism for separating localizable strings from code. Le stringhe tradotte per la lingua non predefinita sono file di risorse con estensione resx isolati.Translated strings for the non-default language are isolated .resx resource files. È possibile ad esempio che si voglia creare un file di risorse spagnolo denominato Welcome.es.resx contenente le stringhe tradotte.For example, you might want to create Spanish resource file named Welcome.es.resx containing translated strings. "es" è il codice di lingua per lo spagnolo."es" is the language code for Spanish. Per creare questo file di risorse in Visual Studio:To create this resource file 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.In Solution Explorer, right click on the folder which will contain the resource file > Add > New Item.

    Menu contestuale annidato: in Esplora soluzioni viene visualizzato un menu contestuale per le risorse.

  2. Nella casella Cerca modelli installati immettere "risorse" e assegnare un nome al file.In the Search installed templates box, enter "resource" and name the 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.Enter the key value (native string) in the Name column and the translated string in the Value column.

    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.Visual Studio shows the Welcome.es.resx file.

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

Denominazione dei file di risorseResource file naming

Le risorse sono denominate con il nome completo del tipo della relativa classe meno il nome dell'assembly.Resources are named for the full type name of their class minus the assembly name. 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.For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx. Una risorsa per la classe LocalizationWebsite.Web.Controllers.HomeController viene denominata Controllers.HomeController.fr.resx.A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named 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.If your targeted class's namespace isn't the same as the assembly name you will need the full type name. Ad esempio, nel progetto di esempio una risorsa per il tipo ExtraNamespace.Tools verrebbe denominata ExtraNamespace.Tools.fr.resx.For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx.

Poiché nel progetto di esempio il metodo ConfigureServices imposta ResourcesPath su "Resources", il percorso relativo del progetto per il file di risorse francese del controller principale è Resources/Controllers.HomeController.fr.resx.In the sample project, the ConfigureServices method sets the ResourcesPath to "Resources", so the project relative path for the home controller's French resource file is Resources/Controllers.HomeController.fr.resx. In alternativa, è possibile usare le cartelle per organizzare i file di risorse.Alternatively, you can use folders to organize resource files. Per il controller principale, il percorso sarà Resources/Controllers/HomeController.fr.resx.For the home controller, the path would be 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.If you don't use the ResourcesPath option, the .resx file would go in the project base directory. Il file di risorse per HomeController sarà denominato Controllers.HomeController.fr.resx.The resource file for HomeController would be named 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.The choice of using the dot or path naming convention depends on how you want to organize your resource files.

Nome della risorsaResource name Denominazione con il punto o il percorsoDot or path naming
Resources/Controllers.HomeController.fr.resxResources/Controllers.HomeController.fr.resx PuntoDot
Resources/Controllers/HomeController.fr.resxResources/Controllers/HomeController.fr.resx PathPath

I file di risorse che usano @inject IViewLocalizer nelle visualizzazioni Razor seguono un modello simile.Resource files using @inject IViewLocalizer in Razor views follow a similar pattern. Il file di risorse per una visualizzazione può essere denominato usando la denominazione con il punto o con il percorso.The resource file for a view can be named using either dot naming or path naming. I file di risorse di visualizzazione Razor simulano il percorso del file di visualizzazione associato.Razor view resource files mimic the path of their associated view file. Se ResourcesPath viene impostato su "Resources", il file di risorse francese associato alla visualizzazione Views/Home/About.cshtml sarà uno dei seguenti:Assuming we set the ResourcesPath to "Resources", the French resource file associated with the Views/Home/About.cshtml view could be either of the following:

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

  • Resources/Views.Home.About.fr.resxResources/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.If you don't use the ResourcesPath option, the .resx file for a view would be located in the same folder as the view.

RootNamespaceAttributeRootNamespaceAttribute

L'attributo RootNamespace specifica lo spazio dei nomi radice di un assembly quando tale spazio dei nomi è diverso dal nome dell'assembly.The RootNamespace attribute provides the root namespace of an assembly when the root namespace of an assembly is different than the assembly name.

Se lo spazio dei nomi radice di un assembly è diverso dal nome dell'assembly:If the root namespace of an assembly is different than the assembly name:

  • Per impostazione predefinita, la localizzazione non funziona.Localization does not work by default.
  • Le risorse vengono cercate all'interno dell'assembly in un modo che impedisce la localizzazione.Localization fails due to the way resources are searched for within the assembly. RootNamespace è un valore necessario in fase di compilazione che non è disponibile per il processo in esecuzione.RootNamespace is a build-time value which is not available to the executing process.

Se l'attributo RootNamespace è diverso da AssemblyName, includere quanto segue in AssemblyInfo.cs, sostituendo i valori dei parametri con quelli effettivi:If the RootNamespace is different from the AssemblyName, include the following in AssemblyInfo.cs (with parameter values replaced with the actual values):

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.The preceding code enables the successful resolution of resx files.

Comportamento di fallback delle impostazioni culturaCulture fallback behavior

Durante la ricerca di una risorsa, la localizzazione esegue un "fallback delle impostazioni cultura".When searching for a resource, localization engages in "culture fallback". A partire dalle impostazioni cultura richieste, se queste non vengono trovate, il codice adotta le impostazioni cultura padre di quelle richieste.Starting from the requested culture, if not found, it reverts to the parent culture of that culture. Tenere presente che la proprietà CultureInfo.Parent rappresenta le impostazioni cultura padre.As an aside, the CultureInfo.Parent property represents the parent culture. Ciò comporta in genere (ma non sempre) la rimozione della notazione nazionale dal codice ISO.This usually (but not always) means removing the national signifier from the ISO. Ad esempio la versione della lingua spagnola parlata in Messico è "es-MX".For example, the dialect of Spanish spoken in Mexico is "es-MX". L'elemento padre è "es", ovvero spagnolo non specifico per nessun paese.It has the parent "es"—Spanish non-specific to any country.

Si supponga che il sito riceva una richiesta di una risorsa "Welcome" che usa le impostazioni cultura "fr-CA".Imagine your site receives a request for a "Welcome" resource using culture "fr-CA". Il sistema di localizzazione cerca le risorse seguenti nell'ordine elencato e seleziona la prima corrispondenza:The localization system looks for the following resources, in order, and selects the first match:

  • Welcome.fr-CA.resxWelcome.fr-CA.resx
  • Welcome.fr.resxWelcome.fr.resx
  • Welcome.resx (se NeutralResourcesLanguage è "fr-CA")Welcome.resx (if the NeutralResourcesLanguage is "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.As an example, if you remove the ".fr" culture designator and you have the culture set to French, the default resource file is read and strings are localized. 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.The Resource manager designates a default or fallback resource for when nothing meets your requested culture. 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.If you want to just return the key when missing a resource for the requested culture you must not have a default resource file.

Generare file di risorse con Visual StudioGenerate resource files with 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.If you create a resource file in Visual Studio without a culture in the file name (for example, Welcome.resx), Visual Studio will create a C# class with a property for each string. In genere questo non è il risultato desiderato quando si usa ASP.NET Core.That's usually not what you want with ASP.NET Core. Solitamente non è presente un file di risorse con estensione resx predefinito (un file con estensione resx senza nome delle impostazioni cultura).You typically don't have a default .resx resource file (a .resx file without the culture name). Si consiglia di creare il file con estensione resx con un nome delle impostazioni cultura, ad esempio Welcome.fr.resx.We suggest you create the .resx file with a culture name (for example 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.When you create a .resx file with a culture name, Visual Studio won't generate the class file. Si prevede che molti sviluppatori non creeranno un file di risorse di lingua predefinita.We anticipate that many developers won't create a default language resource file.

Aggiungere altre impostazioni culturaAdd other cultures

Ogni combinazione di lingua e impostazioni cultura (diversa dalla lingua predefinita) richiede un file di risorse univoco.Each language and culture combination (other than the default language) requires a unique resource file. 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.You create resource files for different cultures and locales by creating new resource files in which the ISO language codes are part of the file name (for example, en-us, fr-ca, and en-gb). I codici ISO vengono inseriti tra il nome file e l'estensione resx come in Welcome.es-MX.resx (spagnolo/Messico).These ISO codes are placed between the file name and the .resx file extension, as in Welcome.es-MX.resx (Spanish/Mexico).

Implementare una strategia per la selezione della lingua o delle impostazioni cultura per ogni richiestaImplement a strategy to select the language/culture for each request

Configurare la localizzazioneConfigure localization

La localizzazione è configurata nel metodo Startup.ConfigureServices:Localization is configured in the Startup.ConfigureServices method:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization aggiunge i servizi di localizzazione al contenitore dei servizi.AddLocalization Adds the localization services to the services container. Il codice precedente imposta anche il percorso delle risorse su "Resources".The code above also sets the resources path to "Resources".

  • AddViewLocalization aggiunge il supporto per i file di visualizzazione localizzati.AddViewLocalization Adds support for localized view files. Nell'esempio la localizzazione delle visualizzazioni è basata sul suffisso dei file di visualizzazione.In this sample view localization is based on the view file suffix. Ad esempio "fr" nel file Index.fr.cshtml.For example "fr" in the Index.fr.cshtml file.

  • AddDataAnnotationsLocalization aggiunge il supporto per i messaggi di convalida DataAnnotations localizzati tramite le astrazioni IStringLocalizer.AddDataAnnotationsLocalization Adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

Middleware di localizzazioneLocalization middleware

Le impostazioni cultura correnti in un richiesta sono impostate nel middleware di localizzazione.The current culture on a request is set in the localization Middleware. Il middleware di localizzazione viene abilitato nel metodo Startup.Configure.The localization middleware is enabled in the Startup.Configure method. Il middleware di localizzazione deve essere configurato prima di qualsiasi middleware che potrebbe controllare le impostazioni cultura della richiesta (ad esempio, app.UseMvcWithDefaultRoute()).The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).

var supportedCultures = new[]
{
    new CultureInfo("en-US"),
    new CultureInfo("fr"),
};

app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("en-US"),
    // Formatting numbers, dates, etc.
    SupportedCultures = supportedCultures,
    // UI strings that we have localized.
    SupportedUICultures = supportedCultures
});

app.UseStaticFiles();
// To configure external authentication, 
// see: http://go.microsoft.com/fwlink/?LinkID=532715
app.UseAuthentication();
app.UseMvcWithDefaultRoute();

UseRequestLocalization inizializza un oggetto RequestLocalizationOptions.UseRequestLocalization initializes a RequestLocalizationOptions object. 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.On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. I provider predefiniti provengono dalla classe RequestLocalizationOptions:The default providers come from the RequestLocalizationOptions class:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

L'elenco predefinito passa dal più specifico al meno specifico.The default list goes from most specific to least specific. Di seguito in questo articolo viene descritto come modificare l'ordine e aggiungere un provider delle impostazioni cultura personalizzato.Later in the article we'll see how you can change the order and even add a custom culture provider. Se nessuno dei provider è in grado di determinare le impostazioni cultura della richiesta, viene usato DefaultRequestCulture.If none of the providers can determine the request culture, the DefaultRequestCulture is used.

QueryStringRequestCultureProviderQueryStringRequestCultureProvider

Alcune app usano una stringa di query per specificare le impostazioni cultura e le impostazioni cultura dell'interfaccia utente.Some apps will use a query string to set the culture and UI culture. Per le app che usano il cookie o l'approccio dell'intestazione Accept-Language, è utile aggiungere una stringa di query all'URL per eseguire il debug e il test del codice.For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. Per impostazione predefinita, QueryStringRequestCultureProvider viene registrato come primo provider di localizzazione nell'elenco RequestCultureProvider.By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider list. Passare i parametri della stringa di query culture e ui-culture.You pass the query string parameters culture and ui-culture. L'esempio seguente specifica le impostazioni cultura specifiche (lingua e area) per spagnolo/Messico:The following example sets the specific culture (language and region) to Spanish/Mexico:

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.If you only pass in one of the two (culture or ui-culture), the query string provider will set both values using the one you passed in. Ad esempio, se si specificano solo le impostazioni cultura verranno impostati entrambi i parametri Culture e UICulture:For example, setting just the culture will set both the Culture and the UICulture:

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

CookieRequestCultureProviderCookieRequestCultureProvider

Le app di produzione offrono spesso la possibilità di specificare le impostazioni cultura con il cookie delle impostazioni cultura di ASP.NET Core.Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Usare il metodo MakeCookieValue per creare un cookie.Use the MakeCookieValue method to create a cookie.

CookieRequestCultureProvider DefaultCookieName restituisce il nome del cookie predefinito usato per tenere traccia delle informazioni di cultura preferite dell'utente.The CookieRequestCultureProvider DefaultCookieName returns the default cookie name used to track the user's preferred culture information. Il nome del cookie predefinito è .AspNetCore.Culture.The default cookie name is .AspNetCore.Culture.

Il formato del cookie è c=%LANGCODE%|uic=%LANGCODE%, dove c è Culture e uic è UICulture, ad esempio:The cookie format is c=%LANGCODE%|uic=%LANGCODE%, where c is Culture and uic is UICulture, for example:

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.If you only specify one of culture info and UI culture, the specified culture will be used for both culture info and UI culture.

Intestazione HTTP Accept-LanguageThe Accept-Language HTTP header

L'intestazione Accept-Language può essere impostata nella maggior parte dei browser ed è stata originariamente progettata per specificare la lingua dell'utente.The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. Questa impostazione indica la lingua impostata per l'invio da parte del browser o che il browser ha ereditato dal sistema operativo sottostante.This setting indicates what the browser has been set to send or has inherited from the underlying operating system. 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)).The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). Un'app di produzione deve consentire all'utente di personalizzare le impostazioni cultura.A production app should include a way for a user to customize their choice of culture.

Impostare l'intestazione HTTP Accept-Language in IESet the Accept-Language HTTP header in IE

  1. Dall'icona a forma di ingranaggio, toccare Opzioni Internet.From the gear icon, tap Internet Options.

  2. Toccare Lingue.Tap Languages.

    Opzioni Internet

  3. Toccare Imposta preferenze lingua.Tap Set Language Preferences.

  4. Toccare Aggiungi una lingua.Tap Add a language.

  5. Aggiungere la lingua.Add the language.

  6. Toccare la lingua e quindi toccare Sposta su.Tap the language, then tap Move Up.

Usare un provider personalizzatoUse a custom provider

Si supponga di voler consentire agli utenti di memorizzare lingua e impostazioni cultura nei database.Suppose you want to let your customers store their language and culture in your databases. È possibile creare un provider per la ricerca di questi valori per l'utente.You could write a provider to look up these values for the user. Il codice seguente illustra come aggiungere un provider personalizzato:The following code shows how to add a custom provider:

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.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
});

Usare RequestLocalizationOptions per aggiungere o rimuovere i provider di localizzazione.Use RequestLocalizationOptions to add or remove localization providers.

Specificare le impostazioni cultura a livello di codiceSet the culture programmatically

Questo progetto di esempio Localization.StarterWeb in GitHub contiene l'interfaccia utente per impostare Culture.This sample Localization.StarterWeb project on GitHub contains UI to set the Culture. Il file Views/Shared/_SelectLanguagePartial.cshtml consente di selezionare le impostazioni cultura dall'elenco delle impostazioni cultura supportate:The Views/Shared/_SelectLanguagePartial.cshtml file allows you to select the culture from the list of supported cultures:

@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 file Views/Shared/_SelectLanguagePartial.cshtml viene aggiunto alla sezione footer del file di layout in modo che sia disponibile in tutte le visualizzazioni:The Views/Shared/_SelectLanguagePartial.cshtml file is added to the footer section of the layout file so it will be available to all views:

<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 metodo SetLanguage imposta il cookie delle impostazioni cultura.The SetLanguage method sets the culture 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 _SelectLanguagePartial.cshtml al codice di esempio per questo progetto.You can't plug in the _SelectLanguagePartial.cshtml to sample code for this project. Il progetto Localization.StarterWeb in GitHub include codice per scorrere RequestLocalizationOptions in una visualizzazione parziale Razor attraverso il contenitore di inserimento delle dipendenze.The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions to a Razor partial through the Dependency Injection container.

Termini relativi alla globalizzazione e alla localizzazioneGlobalization and localization terms

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.The process of localizing your app also requires a basic understanding of relevant character sets commonly used in modern software development and an understanding of the issues associated with them. Sebbene tutti i computer memorizzano il testo come numeri (codici), sistemi diversi memorizzano lo stesso testo usando numeri diversi.Although all computers store text as numbers (codes), different systems store the same text using different numbers. Il processo di localizzazione si riferisce alla traduzione dell'interfaccia utente dell'app per impostazioni cultura o locali specifiche.The localization process refers to translating the app user interface (UI) for a specific culture/locale.

La localizzabilità è un processo intermedio che verifica che un'app globalizzata sia pronta per la localizzazione.Localizability is an intermediate process for verifying that a globalized app is ready for localization.

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.The RFC 4646 format for the culture name is <languagecode2>-<country/regioncode2>, where <languagecode2> is the language code and <country/regioncode2> is the subculture code. Ad esempio, es-CL per spagnolo (Cile), en-US per inglese (Stati Uniti) e en-AU per inglese (Australia).For example, es-CL for Spanish (Chile), en-US for English (United States), and en-AU for English (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.RFC 4646 is a combination of an ISO 639 two-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region. Vedere Language Culture Name (Nome delle impostazioni cultura delle lingue).See Language Culture Name.

L'internazionalizzazione è spesso abbreviata con "I18N".Internationalization is often abbreviated to "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".The abbreviation takes the first and last letters and the number of letters between them, so 18 stands for the number of letters between the first "I" and the last "N". Lo stesso vale per globalizzazione (G11N) e localizzazione (L10N).The same applies to Globalization (G11N), and Localization (L10N).

Termini:Terms:

  • Globalizzazione (G11N): processo che consente a un'app di supportare lingue e aree diverse.Globalization (G11N): The process of making an app support different languages and regions.
  • Localizzazione (L10N): processo di personalizzazione di un'app per una determinata lingua e area.Localization (L10N): The process of customizing an app for a given language and region.
  • Internazionalizzazione (I18N): descrive la globalizzazione e la localizzazione.Internationalization (I18N): Describes both globalization and localization.
  • Impostazioni cultura: si tratta di una lingua e, facoltativamente, di un'area.Culture: It's a language and, optionally, a region.
  • Impostazioni cultura neutre: cultura con una lingua specificata ma senza area.Neutral culture: A culture that has a specified language, but not a region. (ad esempio "en", "es")(for example "en", "es")
  • Impostazioni cultura specifiche: cultura con una lingua e un'area specificate.Specific culture: A culture that has a specified language and region. (ad esempio "en-US", "en-GB", "es-CL")(for example "en-US", "en-GB", "es-CL")
  • Impostazioni cultura padre: impostazioni cultura neutre con impostazioni cultura specifiche.Parent culture: The neutral culture that contains a specific culture. (ad esempio, "en" rappresenta le impostazioni cultura padre di "en-US" e "en-GB")(for example, "en" is the parent culture of "en-US" and "en-GB")
  • Impostazioni locali: le impostazioni locali corrispondono alle impostazioni cultura.Locale: A locale is the same as a culture.

Nota

È possibile che non si riesca a immettere virgole decimali nel campo.You may not be able to enter decimal commas in decimal fields. 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.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Problema 4076 su GitHub per istruzioni sull'aggiunta della virgola decimale.This GitHub issue 4076 for instructions on adding decimal comma.

Risorse aggiuntiveAdditional resources