Mehr von Jürgen Gutsch

Mehr von Jürgen Gutsch

Empfehlungen von Jürgen Gutsch

Blog-Empfehlungen von Jürgen Gutsch

Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Jürgen Gutsch

ASP.NET und mehr...

News

ASP.NET Ressourcen clientseitig mit JavaScript nutzen

In einer ASP.NET Anwendung in der relativ viel JavaScript genutzt wird, bekommt man spätestens dann Probleme, wenn man auch Meldungen und Texte die per JavaScript erzeugt werden, mehrsprachig ausgeben möchte.

Man könnte jetzt einfach alle Scripts serverseitig erzeugen und auf das WebForm rendern, bei vielen JavaScripts macht das allerdings keinen Sinn mehr. Selbst alle Scripts dynamisch über einen HttpHandler ausgeben zu lassen ist nicht sinnvoll, da dann alle Scripts nur als String im .NET Code vorliegen und nur schwer zu Ändern sind (fehlendes Syntax Highlighting, kein IntelliSense, etc).

Das Problem ist jetzt, wie stelle ich alle Resource Strings meiner Webanwendung clientseitig zur Verfügung? Wichtig ist, dass ich die bei einer neuen Ressource nicht wieder Änderungen an zwei Stellen vornehmen muss.

Einen HttpHandler zu benutzen steht außer Frage. Was ich aber nicht möchte, ist jeden Resource String einzeln in den Handler zu schreiben. Bis jetzt kannte ich keine Möglichkeit, eine Collection mit allen Werten aus den Ressourcen zu lesen. Die Beschreibung der ResXResourceReader in der MSDN brachte mich dann auf die annähernd optimale Lösung:

context.Response.ContentType = "text/javascript";
string resourceFilePath = context.Server.MapPath("~/App_GlobalResources/General.resx");
string resourceValue;
string resourceString;

context.Response.Write("var Resources = {\n"); // Start Namespace "Resources"
context.Response.Write("\"General\" : {\n");   // Start Class "General"
using (ResXResourceReader reader = new ResXResourceReader(resourceFilePath))
{
    IDictionaryEnumerator en = reader.GetEnumerator();
    while (en.MoveNext())
    {
        resourceValue = en.Value.ToString();
        resourceValue = resourceValue.Replace("\"", "\\\"");
        resourceValue = resourceValue.Replace("\r\n", "\\n");
               
        resourceString = string.Format("\"{0}\" : \"{1}\",\n",
            en.Key,
            resourceValue);
               
        context.Response.Write(resourceString);
    }
}
context.Response.Write("}\n"); // End Class "General"
context.Response.Write("};\n"); // End Namespace "Resources"

Dieser Handler erzeugt dann z. B: folgende Ausgabe:
var Resources = {
"General" : {
"Add" : "Hinzufügen",
"AllFields" : "Alle Felder",
"Apply" : "Übernehmen",
"AskDelete" : "Aktuellen Datensatz wirklich löschen?",
"Back" : "Zur letzten Seite",
"Cancel" : "Abbrechen",
"Change" : "Bearbeiten",
"CloseModalWindow" : "Schließen",
}
}

Der Handler kann dann ganz normal wie eine JavaScript Datei im WebForm eingebunden werden:
<script src="common/scripts/resources.ashx" type="text/javascript"> </script>

Das schöne an dieser Variante ist, das ich die Ressourcen wie im C# Code nutzen kann:
<asp:Button ID="btnDelete" runat="server" Text="Löschen" 
    onclick="if(confirm(Resources.Genaral.AskDelete))return false;" />

Nachteil an dieser Variante, bzw. eigentlich nur an dem Code des HttpHandlers oben, ist dass die Resource Datei hart reingeschrieben ist. Um das ganz zu optimieren, könnte man alle .RESX Dateien durchgehen, die z. B. unter „App_GlobalResources“ angelegt sind.

Des Weiteren ist die Internationalisierung noch nicht berücksichtigt. Das heißt bei der Ermittlung des Pfades zur Resource Datei muss die aktuelle Culture noch berücksichtigt werden, damit je nach Einstellung die richtigen Dateien gefunden werden. Z. B: („General.de-DE.resx“ für die Deutsche Ausgabe oder „General.en-US.resx“ für die US Amerikanische Ausgabe).

Posted: Dienstag, 5. Februar 2008 10:47 von Jürgen Gutsch

Kommentare

Peter Bucher sagte:

Sehr interessant!

Mit deinen am Schluss angesprochenen Ergänzungen ist das ja ne richtig coole Lösung :-)

# Februar 5, 2008 11:41

kristof sagte:

Warum denn nur alle Resourcen auf einmal laden? In einem meiner Webs requeste ich per AJAX immer nur gerade den String, den ich in dem Moment brauche. Dazu wird der Inhalt einer ASPX (automatisch mit der richtigen Culture) abgerufen und String in die Meldung eingebaut. Wenn man z.B. das jQuery-Framework einsetzt ist das nur ein Einzeiler...

# Februar 7, 2008 12:43

Jürgen Gutsch sagte:

Hallo Kristof,

das ist richtig, setzt aber voraus, dass man Ajax einsetzen möchte (welches auch immer), was sich meiner Meinung nach nicht lohnt, wenn man nur ein paar Strings benötigt, oder aus Performanzgründen nicht immer wieder eine neue HTTP Anfrage senden möchte.

Dennoch danke für deinen berechtigten Einwand :-)

# Februar 7, 2008 22:45
Anonyme Kommentare sind nicht zugelassen