Quando dobbiamo realizzare un'applicazione multilingua, è importante sfruttare al meglio i servizi offerti da ASP.NET Core così che il nostro codice applicativo non si complichi inutilmente a causa di questo requisito.
Per prima cosa, vediamo come consentire all'utente di selezionare una lingua o, per meglio dire, una Culture, cioè l'insieme delle convezioni (date, numeri, idioma) che differenziano ogni regione del mondo dall'altra.
A questo scopo, ASP.NET Core mette a disposizione il RequestLocalizationMiddleware che si occupa di selezionare una Culture in maniera coerente con le informazioni incluse nella richiesta HTTP. Per usarlo, aggiungiamo quanto segue nel metodo Configure della classe Startup.
//L'ordine dei middleware è importante //Mettiamo questo PRIMA di app.UseMvc o app.UseEndpoints app.UseRequestLocalization(options => { //Impostiamo l'italiano come Culture predefinita options.DefaultRequestCulture = new RequestCulture("it"); //Indichiamo quali altre Culture sono supportate dalla nostra applicazione //Qui l'elenco delle Culture con Regione: https://github.com/dotnet/corefx/blob/33e31f98b69bc34e3022f2f4c886251c685b3289/src/Common/src/CoreLib/System/Globalization/CultureData.cs#L171 options.SupportedCultures = options.SupportedUICultures = new [] { new CultureInfo("en-US"), //inglese americano new CultureInfo("fr"), //francese (senza indicare la Regione) new CultureInfo("it") //italiano (senza indicare la Regione) }; });
In queste opzioni è importante impostare sia la proprietà SupportedCultures che la proprietà SupportedUICultures: la prima è responsabile delle convenzioni usate per la formattazione e il parsing di date e numeri, mentre la seconda determina quali file di risorse saranno selezionati per la localizzazione dei testi dell'applicazione.
Il RequestLocalizationMiddleware fa affidamento su 3 provider predefiniti che sono in grado di selezionare una Culture in base a 3 differenti tipi di informazione presenti nella richiesta HTTP:
- La query string, dalle chiavi culture e ui-culture. Fornendo solo una di esse, anche l'altra verrà impostata con lo stesso valore;
- Un cookie chiamato .AspNetCore.Culture il cui valore va impostato ad esempio su c=it|uic=it;
- L'intestazione Accept-Language inviata dal browser, che ci aiuta a preselezionare una Culture quando non è stata espressa alcuna preferenza con le altre due fonti.
Ad esempio, se volessimo consentire all'utente di selezionare una delle lingue supportate dalla nostra applicazione, potremmo preparare dei link come i seguenti, che sfruttano la query string per passare l'informazione sulla Culture desiderata.
<a href="?culture=en-US">English (US)</a> <a href="?culture=it">Italiano</a> <a href="?culture=fr">Français</a>
Data la natura estendibile di ASP.NET Core, il middleware può comunque avvalersi di provider personalizzati, che determineranno la Culture in base ad altre fonti. Nella documentazione ufficiale si trova un esempio: https://docs.microsoft.com/it-it/aspnet/core/fundamentals/localization?view=aspnetcore-2.2#use-a-custom-provider.
A questo punto, per conoscere qual è la Culture selezionata da un'action di ASP.NET Core MVC, possiamo usare il codice del seguente esempio.
public IActionResult Index() { string culture = CultureInfo.CurrentCulture.Name; //Qui uso il valore di culture, che sarà en-US oppure it oppure fr, //cioè il nome di una delle Culture che stiamo supportando return View(); }
Possiamo recuperare il valore della Culture selezionata anche da una view Razor. L'informazione ci potrebbe essere utile per aggiungere una classe CSS al link attivo, così da evidenziarlo.
@using Microsoft.AspNetCore.Localization @{ string culture = CultureInfo.CurrentCulture.Name; } @* TODO: potremmo generare questi link con un tag helper personalizzato, per migliorare la leggibilità *@ <a href="?culture=en-US" class="@(culture == "en-US" ? "active" : "")">English (US)</a> <a href="?culture=it" class="@(culture == "it" ? "active" : "")">Italiano</a> <a href="?culture=fr" class="@(culture == "fr" ? "active" : "")">Français</a>
Il nome della Culture selezionata lo possiamo ottenere anche dagli altri componenti della nostra applicazione, come per esempio da un servizio applicativo o da un tag helper personalizzato, che ci permetta di generare i link per la selezione della Culture in maniera più leggibile.
[HtmlTargetElement("culture-link", TagStructure = TagStructure.NormalOrSelfClosing)] public class CultureLinkTagHelper : TagHelper { [HtmlAttributeName("for")] public string For { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { //Leggo la Culture attualmente selezionata string culture = CultureInfo.CurrentCulture.Name; //Genero il link output.TagName = "a"; output.TagMode = TagMode.StartTagAndEndTag; output.Attributes.Add("href", $"?culture={For}"); //Il link avrà la classe "active" solo il suo attributo For corrisponde alla Culture selezionata if (culture == For) { output.Attributes.Add("class", "active"); } } }
Infine, ecco un esempio di come usare il tag helper che abbiamo appena realizzato all'interno di una view Razor.
@addTagHelper *, NomeDellAssemblyDelNostroProgetto <culture-link for="en-US">English (US)</culture-link> <culture-link for="it">Italiano</culture-link> <culture-link for="fr">Français</culture-link>
In un prossimo script vedremo come localizzare i testi, ovvero come presentare all'utente i contenuti nella sua lingua, in base alla Culture selezionata.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Registrare servizi multipli tramite chiavi in ASP.NET Core 8
Effettuare il binding di date in Blazor
Paginare i risultati con QuickGrid in Blazor
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Ottimizzazione dei block template in Angular 17
Eseguire query manipolando liste di tipi semplici con Entity Framework Core
Eseguire una GroupBy per entity in Entity Framework
Sfruttare lo streaming di una chiamata Http da Blazor
Eseguire query manipolando le liste contenute in un oggetto mappato verso una colonna JSON
Potenziare Azure AI Search con la ricerca vettoriale
Migrare una service connection a workload identity federation in Azure DevOps
I più letti di oggi
- Utilizzare Docker Compose con Azure App Service
- Utilizzare QuickGrid di Blazor con Entity Framework
- Modernizzare le applicazioni WPF e Windows Forms con Blazor
- ASP 3 per esempi
- annunciato #netstandard 2.1. .NET Core lo supporterà a partire da #netcore3, così come le prossime versione di #xamarin, #mono e #unity.il supporto per #netfx 4.8, invece, non ci sarà. https://aspit.co/bq2