ASP.NET mette a disposizione alcune funzionalità di localizzazione grazie a particolari file di risorsa (Resources in inglese) e provider per accedere a questi file che funzionano come dei contenitori in cui è possibile memorizzare sia coppie di stringhe (chiave-valore), sia file interi.
I file di risorsa si dividono in locali e globali. I primi sono utilizzati per memorizzare valori di cui avremo bisogno in una pagina specifica e prendono il nome dalla pagina a cui si riferiscono: ad esempio default.aspx.resx
o default.aspx.it-IT.resx
a seconda della lingua di riferimento.
I file globali sono invece utili per memorizzare valori che con molta probabilità si ripeteranno su più pagine e che altrimenti sarebbero stati separati (e molto probabilmente ripetuti) in diversi file locali. Le risorse globali sono posizionate all'interno della cartella ~/App_GlobalResources
.
Vedremo come accedere alle risorse durante la costruzione del nostro sito di esempio, che si comporrà di una sola pagina (Default.aspx
).
Per la costruzione del sito è possibile utilizzare sia Visual Studio che la versione Express di Visual Web Developer.
Creazione del progetto
Cominciamo creando il nostro progetto: scegliamo Nuovo Sito Web dal menu File, quindi selezioniamo C# come linguaggio e, se stiamo lavorando con la versione 2008 di Visual Studio, il Framework .Net 2.0 come spazio di lavoro.
Dopo aver premuto OK, aggiungiamo subito le cartelle App_GlobalResources
e App_LocalResources
al progetto:
Cominciamo quindi a creare i file di risorsa necessari. Per mostrare le potenzialità di ASP.NET avremo bisogno di quattro file distinti: due per le risorse locali (da aggiungere quindi alla cartella App_LocalResources
) che chiameremo Default.aspx.resx
e Default.aspx.it-IT.resx
, e due per le risorse globali: Common.resx
e Common.it-IT.aspx
.
Se tutto è andato a buon fine, dovremmo vedere i nuovi file nel progetto.
Cominciamo quindi ad aggiungere le stringhe (e le rispettive chiavi) all'interno dei file di risorsa. Compiliamo quindi tutte le tabelle. Le chiavi rimarranno uguali per ogni file, mentre i valori cambieranno a seconda della lingua.
Quando selezioniamo una lingua, ASP.NET cerca automaticamente all'interno del file di risorsa la stringa localizzata, eseguendo una ricerca sulle chiavi.
Nota: abbiamo creato i resource files all'interno dell'ambiente di sviluppo per comodità, ma avremmo anche potuto scriverli a mano visto che si tratta di semplici file XML.
Passiamo ora al codice della pagina principale (Default.aspx)
Default.aspx
<form id="form1" runat="server"> <div> <asp:Label ID="ChangeLabel" runat="server" meta:resourcekey="ChangeLabel" /> <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Value="default">Default</asp:ListItem> <asp:ListItem Value="it-IT">it-IT</asp:ListItem> </asp:DropDownList> <asp:Button ID="SetLang" runat="server" Text="<%$ Resources:Common, Change %>" ToolTip="<%$ Resources:Common, ChangeToolTip %>" /> </div> </form>
La struttura è molto semplice: abbiamo inserito all'interno della pagina tre controlli lato server. Il primo è una Label
, cui assegniamo implicitamente i valori contenuti nei file di risorsa attraverso l'attributo:
meta:resourcekey="ChangeLabel"
ASP.NET cercherà quindi nelle resources le chiavi che iniziano con ChangeLabel
e applicherà al controllo le proprietà che seguono il nome della chiave. Nel nostro caso la chiave ChangeLabel.Text
verrà applicata alla proprietà Text
del controllo Label
.
Il secondo controllo che inseriamo è una DropDownList
. In questo caso non viene recuperato alcun valore dai file di risorsa. Popoliamo infatti manualmente la lista di valori con i nomi delle lingue supportate dal nostro sito di esempio.
Questo controllo unito al successivo Button
servirà infatti a cambiare la lingua.
Per completezza nel Button
ho utilizzato il metodo esplicito per assegnare i valori alle proprietà del controllo:
<%$ Resources: NomeFileRisorsa, NomeChiave %>
che nel nostro caso diventa:
<%$ Resources:Common, Change %>
In questo modo andiamo a recuperato dal file globale Common
la chiave Change
. Avremmo potuto comunque utilizzare nuovamente il metodo implicito o entrambi.
Prima di mostrare il risultato vediamo che sintassi utilizzare nel code behind della pagina per cambiare lingua a seconda dell'elemento selezionato della DropDownList
quando viene premuto il bottone.
Ovverride di InitiazlizeCulture()
protected override void InitializeCulture() { string culture = Request.Form["DropDownList1"]; CultureInfo c; if (!string.IsNullOrEmpty(culture)) if (culture == "default") { c = CultureInfo.CreateSpecificCulture("en-US"); Thread.CurrentThread.CurrentCulture = c; Thread.CurrentThread.CurrentUICulture = c; } else { c = CultureInfo.CreateSpecificCulture(culture); Thread.CurrentThread.CurrentCulture = c; Thread.CurrentThread.CurrentUICulture = c; } base.InitializeCulture(); } protected void Page_Load(object sender, EventArgs e) { this.Title = GetLocalResourceObject("PageTitle").ToString(); }
Il codice forse é leggermente diverso da come lo si potrebbe aspettare. Non c'è infatti una funzione SetLang_Click
per intercettare la pressione del tasto.
L'inizializzazione della lingua della pagina può avvenire infatti soltanto nel metodo InitializeCulture
. Un altro elemento importante da considerare è che questa funzione viene richiamata prima che ASP.NET costruisca la lista dei controlli della pagina, per cui non avremo accesso alle loro proprietà.
Dovremo quindi estrarre la lingua dalla lista dei valori contenuti nella collection Request.Form
. Verifichiamo quindi quale lingua è stata scelta ed applichiamola al nostro sito con le seguenti istruzioni:
c = CultureInfo.CreateSpecificCulture(culture); Thread.CurrentThread.CurrentCulture = c; Thread.CurrentThread.CurrentUICulture = c;
Se vogliamo invece ottenere una risorsa tramite codice, dobbiamo utilizzare la sintassi:
this.Title = GetLocalResourceObject("PageTitle").ToString();
che in questo caso caricherà dinamicamente il titolo della nostra pagina. Ed ecco come si presenta la pagina nelle due lingue:
Il progetto che abbiamo realizzato è disponibile nel file allegato all'articolo.