Übersetzungen in Blazor Server App
In diesem Tutorial zeige ich wie ich in meiner App die Übersetzungen in Blazor Server implementiert habe. Mit den Boardmitteln von ASP.NET Core ist der Aufwand äußerst gering.
Übersetzungen in Blazor Server App
In den letzten Tutorials habe ich gezeigt wie man Serilog als Logger einbindet. Damit ist die App schon mal recht gesprächig. Jetzt müssen wir noch dafür sorgen, dass diese Meldungen in der Sprache des Anwenders ausgegeben werden. Dazu implementiere ich eine Translator Klasse:
public interface ITranslator { string Translate(string text); } public class Translator : ITranslator { private readonly IStringLocalizer _localizer; public Translator(IStringLocalizer localizer) { _localizer = localizer; } public string Translate(string text) { return _localizer; } }
Ich erstelle ein Interface mit einer Translate Methode die aus einem übergebenen Text einen Text der aktuell eingestellten Sprache zurück gibt (sofern vorhanden). Danach wird dieses Interface implementiert. Es wird das IStringLocalizer Interface injected, von dem Objekt holen wir in der Translate Methode die Übersetzung. Einfach oder?
Damit wir diesen Übersetzer im Frontend und im Backend injected werden können muss er noch als Singleton registriert werden. Der nötige Zusatz in der Startup.cs Datei. In der ConfigureServices Methode werden folgende Zeilen ergänzt:
services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddSingleton<ITranslator, Translator>();
Die zweite Änderung betrifft die Configure Methode:
// translation and localization var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("de"), }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("de"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures });
Im supportedCultures Array werden alle unterstützten Sprachen definiert. In meinem Fall für die erste Ausbaustufe Deutsch und Englisch. Im nächsten Schritt wird die Middleware konfiguriert, dazu erstellt man ein neues RequestLocalizationOptions Object und übergibt dieses der UseRequestLocalization Methode. Wichtig: die DefaultRequestCulture gibt die default Sprache an. In meinem Fall sind so ohne Änderung alle Texte auf deutsch (sofern die Übersetzung korrekt funktioniert!).
Konfiguration
Bevor nun die ersten Texte übersetzt werden können brauchen wir noch eine Quelle mit den übersetzten Wörtern und Sätzen. In einer .NET Core Applikation werden Ressourcendateien (*.resx) genutzt um diese Informationen zu speichern. Die Verwendung eines „üblichen“ Formats hat den großen Vorteil, dass diese von einer Übersetzungsabteilung erstellt werden kann die keine Programmierfähigkeiten haben muss. Für *.resx Dateien findet man zahlreiche Editoren.
Ein Screenshot meiner Übersetzungsdatei:
Das Vorgehen ist wie folgt:
- man erstellt die Applikation in einer beliebigen Sprache. Englisch ist dafür optimal, da so die größte Userbase auch ohne Übersetzung interagieren kann.
- für jede Sprache legt man eine *.resx Datei an
- Dateiname der Übersetzungsdatei ist der vollständige Dateiname der Übersetzungsklasse mit .de.resx wobei de das Sprachkürzel ist. Französisch würde die Endung .fr.resx haben.
Die *.resx Dateien liegen bei mir im Ordner Resource, direkt im Hauptordner des Projekts. Der Name kann geändert werden und ist in der ersten Zeile der ConfigureServices Methode in der Startup.cs Datei definiert.
Übersetzen
Texte werden nun durch den Aufruf der Translate Methode der Translator Klasse übersetzt. Das funktioniert sowohl im Frontend, also den *.razor Dateien als auch im C# Programmcode. Beispiele gefällig?
Frontend
Im Frontend wird die erstellte Translator Klasse mit einem
@inject ITranslator translator
ein beliebiger Text wird übersetzt indem man ihn an die Translate Methode übergibt:
@translator.Translate("Sponsor")
Backend
Genau die selbe Situation haben wir im Backend. In einer beliebigen Klasse muss deshalb der Translator mit dependency injection eingebunden werden:
public class SponsorService { private readonly ITranslator _translator; public SponsorService(ITranslator translator) { _translator = translator; } public void DoSomething() { var translation = _translator.Translate("SomeString"); } }
Danach ruft man die Übersetzungsmethode auf und bekommt den übersetzten Text retour.
Probleme
Bei mir hat die Übersetzung nicht gleich funktioniert und ich denke auch der eine oder andere Leser steht vor einem ähnlichen Problem. Wenn die Applikation ohne Fehler baut, die Texte aber nicht übersetzt ausgegeben werden, dann ist aus irgend einem Grund die Ressource mit den übersetzten Texten nicht bekannt. Folgendes ist zu prüfen:
- Startup.cs, Configure Methode: ist DefaultRequestCulture tatsächlich auf die Sprache gesetzt, für die eine Übersetzung angelegt wurde?
- Ist der Dateiname des Ressource Ordners korrekt (wird in der ConfigureServices Methode angegeben)?
- Ist in Visual Studio definiert, dass die Resource Datei mit kopiert wird?
- Dateinamen prüfen! Passt der Dateiname der Ressourcendatei zur gewünschten Sprache und ist der gesamte Pfad enthalten (meine Translator.cs Datei liegt im Services Ordner!)?
Fazit
Ich habe sehr ausführlich beschrieben wie man Übersetzungen in Blazor Server implementiert. Die .NET Core Umgebung liefert bereits die Funktionalität und es macht Sinn diese auch zu nutzen. Meine in Englisch geschriebenen Texte wird nun sofern die Übersetzung vorhanden ist deutsch angezeigt. Im nächsten Schritt muss noch ein Schalter implementiert werden um die Sprache über die Settings zur Laufzeit umzuschalten, das ist aber nur eine kleine Aufgabe.