Come abbiamo visto nei precedenti articoli, abbiamo utilizzato dei files RESX per avere le traduzioni. È vero che lato front-end quasi non abbiamo scelta, ma lato back-end potremmo anche scegliere di utilizzare un database. In ogni caso avremo bisogno di gestire dei files RESX e generarli.
Cosa sono i files RESX
I files RESX sono files di risorse che affondano le loro origini al lontano C++ e Visual C++ e che sono rimasti pressoché invariati fino ad oggi, tranne per il modo di usarli. Ovviamente non vi tedio sulla storia di questi files ma mi focalizzo su quello che ci servirà nell’ambito .NET e Blazor.
I files con estensione .resx
sono chiamati Managed Resource Files e utilizzati quindi prettamente in ambito .NET. Essi possono contenere qualunque cosa, dal testo alle immagini, editabili tramite l’apposito menù in Visual Studio.


Le nostre risorse verranno poi visualizzate tutte assieme nel file a seconda del tipo di risorse scelto.

Da Visual Studio è semplicissimo creare un file di risorse che contiene tutto quello di cui ho bisogno.
Ma se volessi farlo da un programma esterno? Il tipico scenario per le traduzioni in lingua è il seguente:
- Mando un file CSV o testo generico o (se il traduttore è esperto) in un foglio Excel contenente le traduzioni come chiave-valore. La chiave serve a noi per recuperare la traduzione, il valore serve al traduttore per localizzare il testo in lingua
- Il traduttore rimanda a noi questi files che vengono caricati su un database centrale come chiave-valore per ogni singola lingua
- Tutte i team software recuperano le traduzioni da questo database centralizzato
Ecco che entra in gioco un software esterno per creare i files resx. Non potremmo mai pensare di ricrearci a mano un file di risorse copiando e incollando ogni voce del database su un nostro file resx.
Creare RESX da un file CSV
Per poter creare un file RESX da codice, abbiamo bisogno di installare il nuget package “ICSharpCode.Decompiler“. Esso ci metterà a disposizione la classe ResXResourceWriter che servirà a scrivere il nostro nuovo file di risorse come un’insieme di “chiave-valore”.
Ora, per semplificare l’esempio, prendiamo un foglio Excel come base dati e archivio delle nostre lingue. Ovviamente potremmo avere come fonte di dati un database esterno, un servizio, un file di testo o qualunque altra cosa ci passi per la testa.
Creeremo il nostro foglio Excel con diversi fogli al suo interno. Uno per ogni lingua. Andremo poi ad esportare un foglio alla volta usando le seguenti nomenclature:
- Language.csv
- Language.it.csv
- Language.fr.csv
Questi files conterranno i testi “chiave-valore” con le nostre traduzioni
Home,Home
Counter,Contatore
Weather,Meteo
Increment,Incremento
helloworld,Ciao Mondo!
welcome,Benvenuti nella nuova applicazione Blazor
A questo punto non ci resta che creare una nuova applicazione console e mettere i files CSV nella stessa cartella per poterli correttamente gestire. In Esplora Soluzione scegliamo i nostri files uno alla volta e nella finestra proprietà gli diremo di copiarlo sempre nell’output di progetto

Così facendo non dovremo cercare i files in giro per il PC ma saranno nell’output di progetto ovvero la cartella bin dove ci sarà anche il nostro eseguibile. Tengo sempre a precisare che questa è una semplificazione e che in un’applicazione reale potremmo avere un servizio esterno o un database.
Quindi dopo aver creato i files CSV e averli correttamente importati in un’applicazione console, scriviamo le poche righe di codice che serviranno alla generazione dei files di risorsa.
Ecco il file Program.cs cosa conterrà:
using ICSharpCode.Decompiler.Util;
var actualDir = Path.GetDirectoryName(Environment.ProcessPath);
var r = Directory.GetFiles(actualDir == null ? String.Empty : actualDir, "*.csv");
foreach (var resxFile in r)
{
var content = File.ReadAllText(resxFile).Split(Environment.NewLine);
var cultureFileName = resxFile.Substring(resxFile.LastIndexOf('\\') + 1).Replace("Resource", "").Replace(".csv", "");
if(!Directory.Exists(@$"{actualDir}\Resources"))
{
Directory.CreateDirectory(@$"{actualDir}\Resources");
}
using (ResXResourceWriter resx = new ResXResourceWriter(@$"{actualDir}\Resources\Language{cultureFileName}.resx"))
{
foreach (var line in content)
{
if (line.Length > 0)
resx.AddResource(line.Split(",")[0], line.Split(",")[1]);
}
}
}
Una volta fatto correttamente tutto questo, siamo pronti ad avviare l’applicazione e verificarne l’output. Nella cartella ConsoleAppResx\bin\Debug\net6.0\Resources
troveremo i nostri files di risorsa da poter utilizzare nelle nostre applicazioni.
Come al solito potrete trovare il codice completo sul repository GitHub.
E non finisce qui
Ecco! Non è ancora finito l’articolo. Questa volta, grazie alla segnalazione di Carmine Quartarone, vi parlerò anche di un’estensione per Visual Studio molto interessante. Si tratta di ResXManager. Una volta installata nelle estensioni di Visual Studio, sarà disponibile nel menù Strumenti (Tools).

L’interfaccia dell’estensione, ci permetterà di fare molte cose, tra cui aggiungere una lingua, cambiare la lingua di default e (cosa più importante) tradurre tramite alcuni servizi online tra cui Google e Bing.

Dopo aver aggiunto la nostra nuova lingua al progetto, possiamo vedere un’interfaccia di questo tipo:

dove vedremo chiaramente la nuova lingua aggiunta ma senza testi. Ora un comportamento un po’ bizzarro che ho trovato è il seguente: se non si edita un campo, il corrispondente file di risorse non viene creato. Basta saperlo…!
Quindi scegliamo la lingua da tradurre e la lingua di partenza oltre che al nostro servizio di traduzioni preferito (e al quale siamo iscritti) e possiamo tradurre

Premiamo il tasto START e… voilà, tutto tradotto

Se non avete nessun “abbonamento” per le traduzioni, potete registrarvi gratis su google a questo indirizzo https://console.cloud.google.com/apis/api/translate.googleapis.com/credentials e poi mettere la API KEY nell’apposita casellina della finestra ResXManager.

Questo tipo di servizio è utilissimo soprattutto per progetti di piccole dimensioni o basso budget, quando le traduzioni possono anche essere fatte in automatico. Il processo descritto in precedenza (generazione di resx partendo da un database) è sempre il procedimento che io consiglio per applicazioni che si appoggiano ad agenzie di traduzione e quindi applicazioni enterprise.
L’estensione ResXManager consigliatami da Carmine Quartarone ormai fa parte della mia “cassetta degli attrezzi” di Visual Studio perché velocizza e risolve una serie di problemi velocemente e prima che arrivino i testi dalle agenzie di traduzione.
Alla prossima!