Rendere localizzabile il contenuto di un'app ASP.NET Core
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
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 9 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Di Hisham Bin Ateya, Damien Bowden, Bart Calixto e Nadeem Afana
Un'attività per la localizzazione di un'app consiste nel eseguire il wrapping di contenuto localizzabile con codice che facilita la sostituzione del contenuto per impostazioni cultura diverse.
IStringLocalizer
IStringLocalizer e IStringLocalizer<T> sono stati progettato per migliorare la produttività durante lo sviluppo di app localizzate. IStringLocalizer
usa e ResourceManager ResourceReader 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.
Nell'esempio di codice seguente viene illustrato 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. Si sviluppa un'app con la lingua predefinita e la si prepara per il passaggio 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 di non avere un file resx di linguaggio predefinito e il semplice wrapping dei valori letterali stringa può ridurre il sovraccarico di localizzazione di un'app. Altri sviluppatori preferiscono il flusso di lavoro tradizionale in quanto possono essere più facili da usare con valori letterali stringa lunghi e più facile aggiornare stringhe localizzate.
IHtmlLocalizer
Usare l'implementazione IHtmlLocalizer<TResource> per le risorse che contengono HTML. IHtmlLocalizer Codifica HTML gli argomenti formattati nella stringa di risorsa, ma non la codifica HTML della stringa di risorsa stessa. Nel codice evidenziato seguente, solo il valore del name
parametro è 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.
IStringLocalizerFactory
Al livello più basso, IStringLocalizerFactory può essere recuperato da 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."];
return View();
}
Il codice precedente illustra ognuno dei due metodi di creazione factory.
Risorse condivise
È possibile partizionare le stringhe localizzate in base al controller o all'area oppure avere un solo contenitore. Nell'app di esempio viene usata una classe marcatore denominata SharedResource
per le risorse condivise. La classe marcatore non viene mai chiamata:
// Dummy class to group shared resources
namespace Localization;
public class SharedResource
{
}
Nell'esempio seguente vengono usati i InfoController
localizzatori 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 risorse e IViewLocalizer
codifica 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 i valori seguenti:
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.
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
using System.ComponentModel.DataAnnotations;
namespace Localization.ViewModels.Account;
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.
Come usare una 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:
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
Nel codice precedente è SharedResource
la classe corrispondente al file resx in cui vengono archiviati i messaggi di convalida. Con questo approccio, DataAnnotations usa SharedResource
solo , anziché la risorsa per ogni classe.
Configurare i servizi di localizzazione
I servizi di localizzazione sono configurati in Program.cs
:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization aggiunge i servizi di localizzazione al contenitore dei servizi, incluse le implementazioni per
IStringLocalizer<T>
eIStringLocalizerFactory
. Il codice precedente imposta anche il percorso delle risorse su "Resources".AddViewLocalization aggiunge il supporto per i file di visualizzazione localizzati. In questo esempio, la localizzazione delle visualizzazioni si basa sul suffisso del file di visualizzazione. Ad esempio , "fr" nel
Index.fr.cshtml
file .AddDataAnnotationsLocalization aggiunge il supporto per i messaggi di convalida localizzati
DataAnnotations
tramiteIStringLocalizer
astrazioni.
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 .
Passaggi successivi
La localizzazione di un'app comporta anche le attività seguenti:
- Fornire risorse localizzate per le lingue e le impostazioni cultura supportate dall'app
- Implementare una strategia per selezionare la lingua/le impostazioni cultura per ogni richiesta
Risorse aggiuntive
- Provider di impostazioni cultura url che usano il middleware come filtri in ASP.NET Core
- Applicazione globale di RouteDataRequest CultureProvider con middleware come filtri
- Globalizzazione e localizzazione in ASP.NET Core
- Fornire risorse localizzate per lingue e impostazioni cultura in un'app core ASP.NET
- Strategie per la selezione di lingua e impostazioni cultura in un'app ASP.NET Core localizzata
- Risolvere i problemi di localizzazione di ASP.NET Core
- Globalizzazione e localizzazione di applicazioni .NET
- Progetto Localization.StarterWeb usato nell'articolo.
- Uso dei file RESX a livello di codice
- Microsoft Multilingual App Toolkit
- Localizzazione e generics
Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya
Un'attività per la localizzazione di un'app consiste nel eseguire il wrapping di contenuto localizzabile con codice che facilita la sostituzione del contenuto per impostazioni cultura diverse.
IStringLocalizer
IStringLocalizer e IStringLocalizer<T> sono stati progettato per migliorare la produttività durante lo sviluppo di app localizzate. IStringLocalizer
usa e ResourceManager ResourceReader 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.
Nell'esempio di codice seguente viene illustrato 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. Si sviluppa un'app con la lingua predefinita e la si prepara per il passaggio 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 di non avere un file resx di linguaggio predefinito e il semplice wrapping dei valori letterali stringa può ridurre il sovraccarico di localizzazione di un'app. Altri sviluppatori preferiscono il flusso di lavoro tradizionale in quanto possono essere più facili da usare con valori letterali stringa lunghi e più facile aggiornare stringhe localizzate.
IHtmlLocalizer
Usare l'implementazione IHtmlLocalizer<T>
per le risorse che contengono HTML. IHtmlLocalizer
Codifica HTML gli argomenti formattati nella stringa di risorsa, ma non la codifica HTML della stringa di risorsa stessa. Nel codice evidenziato seguente, solo il valore del name
parametro è 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.
IStringLocalizerFactory
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 factory.
Risorse condivise
È possibile partizionare le stringhe localizzate in base al controller o all'area oppure avere un solo 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 InfoController
localizzatori 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 risorse e IViewLocalizer
codifica 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 i valori seguenti:
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; }
}
In ASP.NET Core MVC 1.1.0 e versioni successive, gli attributi di non convalida vengono localizzati.
Come usare una 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 resx in cui vengono archiviati i messaggi di convalida. Con questo approccio, DataAnnotations usa SharedResource
solo , anziché la risorsa per ogni classe.
Configurare i servizi di localizzazione
I servizi di localizzazione vengono configurati nel Startup.ConfigureServices
metodo :
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization
aggiunge i servizi di localizzazione al contenitore dei servizi, incluse le implementazioni perIStringLocalizer<T>
eIStringLocalizerFactory
. Il codice precedente imposta anche il percorso delle risorse su "Resources".AddViewLocalization
aggiunge il supporto per i file di visualizzazione localizzati. In questo esempio, la localizzazione delle visualizzazioni si basa sul suffisso del file di visualizzazione. Ad esempio , "fr" nelIndex.fr.cshtml
file .AddDataAnnotationsLocalization
aggiunge il supporto per i messaggi di convalida localizzatiDataAnnotations
tramiteIStringLocalizer
astrazioni.
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 .
Passaggi successivi
La localizzazione di un'app comporta anche le attività seguenti:
- Fornire risorse localizzate per le lingue e le impostazioni cultura supportate dall'app
- Implementare una strategia per selezionare la lingua/le impostazioni cultura per ogni richiesta
Risorse aggiuntive
- Globalizzazione e localizzazione in ASP.NET Core
- Fornire risorse localizzate per lingue e impostazioni cultura in un'app core ASP.NET
- Strategie per la selezione di lingua e impostazioni cultura in un'app ASP.NET Core localizzata
- Risolvere i problemi di localizzazione di ASP.NET Core
- Globalizzazione e localizzazione di applicazioni .NET
- Progetto Localization.StarterWeb usato nell'articolo.
- Uso dei file RESX a livello di codice
- Microsoft Multilingual App Toolkit
- Localizzazione e generics