Gestire la localizzazione con ASP.NET Core

di Moreno Gentili, in ASP.NET Core,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi