Empfehlungen für die Entwicklung weltweit einsatzfähiger Anwendungen

In diesem Abschnitt wird die empfohlene Vorgehensweise zum Entwickeln von weltweit einsatzfähigen Anwendungen beschrieben.

Bewährte Methoden für die Globalisierung

  1. Erstellen Sie den Anwendungs-Unicode intern.

  2. Verwenden Sie die vom System.Globalization-Namespace bereitgestellten kulturfähigen Klassen, um Daten zu ändern und zu formatieren.

    • Verwenden Sie zum Sortieren die SortKey-Klasse und die CompareInfo-Klasse.
    • Verwenden Sie für Zeichenfolgenvergleiche die CompareInfo-Klasse.
    • Verwenden Sie zum Formatieren von Datum und Uhrzeit die DateTimeFormatInfo-Klasse.
    • Verwenden Sie zum Formatieren von numerischen Daten die NumberFormatInfo-Klasse.
    • Verwenden Sie für gregorianische und nicht gregorianische Kalender die Calendar-Klasse oder eine spezifische Implementierung von Calendar.
  3. Verwenden Sie die in den entsprechenden Situationen von der System.Globalization.CultureInfo-Klasse bereitgestellten Kultureigenschafteneinstellungen. Verwenden Sie für Formatierungsaufgaben (wie das Formatieren von Datum und Uhrzeit oder zum Formatieren numerischer Daten) die CultureInfo.CurrentCulture-Eigenschaft. Verwenden Sie zum Abrufen von Ressourcen die CultureInfo.CurrentUICulture-Eigenschaft. Die CurrentCulture-Eigenschaft und die CurrentUICulture-Eigenschaft können für jeden Thread einzeln festgelegt werden.

  4. Aktivieren Sie für die Anwendung das Lesen und Schreiben von Daten für eine Vielzahl von Codierungen, indem Sie die Codierungsklassen im System.Text-Namespace verwenden. Gehen Sie nicht von ASCII-Daten aus. Gehen Sie davon aus, dass internationale Zeichen überall dort zur Verfügung gestellt werden, wo der Benutzer Text eingeben kann. Beispielsweise sollte die Anwendung internationale Zeichen in Servernamen, Verzeichnissen, Dateinamen, Benutzernamen und URLs akzeptieren.

  5. Wenn Sie die UTF8Encoding-Klasse verwenden, sollten Sie aus Sicherheitsgründen die von dieser Klasse bereitgestellte Fehlererkennungsfunktion verwenden. Erstellen Sie zum Aktivieren der Fehlererkennungsfunktion eine Instanz der Klasse mit dem Konstruktor, der einen throwOnInvalidBytes-Parameter akzeptiert, und legen Sie den Wert dieses Parameters auf true fest.

  6. Behandeln Sie Zeichenfolgen möglichst als ganze Zeichenfolgen und nicht als eine Reihe einzelner Zeichen. Dies ist besonders beim Sortieren von und Suchen nach untergeordneten Zeichenfolgen von Bedeutung. Dadurch werden Probleme vermieden, die beim Analysieren von kombinierten Zeichen auftreten können. Sie können auch mit Texteinheiten anstatt mit einzelnen Zeichen arbeiten, indem Sie die Klasse System.Globalization.StringInfo verwenden.

  7. Zeigen Sie Text mithilfe der Klassen im System.Drawing-Namespace an.

  8. Damit die betriebssystemübergreifende Konsistenz gewährleistet ist, dürfen Benutzereinstellungen CultureInfo nicht überschreiben. Verwenden Sie den CultureInfo-Konstruktor, der einen useUserOverride-Parameter akzeptiert, und legen Sie diesen auf false fest.

  9. Testen Sie die Funktionsfähigkeit der Anwendung in internationalen Betriebssystemen und mit internationalen Daten.

  10. Wenn eine Sicherheitsentscheidung auf dem Ergebnis eines Zeichenfolgenvergleichs oder der Änderung der Groß-/Kleinschreibung beruht, sollten Sie eine kulturunabhängige Zeichenfolgenoperation verwenden. Auf diese Weise stellen Sie sicher, dass das Ergebnis nicht vom Wert von CultureInfo.CurrentCulture beeinflusst wird. Im Abschnitt Zeichenfolgenvergleiche mit der aktuellen Kultur im Artikel Empfohlene Vorgehensweisen für die Verwendung von Zeichenfolgen in .NET finden Sie ein Beispiel, das veranschaulicht, wie kulturabhängige Zeichenfolgenvergleiche zu inkonsistenten Ergebnissen führen können.

  11. Verwenden Sie CultureInfo für Elemente, die für den Austausch (z. B. Felder in einem JSON-Dokument in einem API-Aufruf) oder zur Speicherung verwendet werden. Zusätzlich sollten Sie explizit ein Roundtripformat angeben (z. B. den "O", "o" DateTime-Formatbezeichner). Obwohl die Formatzeichenfolgen für die invariante Kultur stabil sind und sich wahrscheinlich nicht ändern, kann die Angabe einer expliziten Formatzeichenfolge dazu beitragen, die Absicht Ihres Codes zu verdeutlichen.

    • Berücksichtigen Sie für DateTime-Elemente die Hinweise und Beobachtungen des Noda Time-Autors Jon Skeet, der wertvolle Erkenntnisse teilt. Weitere Informationen finden Sie unter Jon Skeet: Storing UTC is not a silver bullet.
  12. Globalisierungsdaten sind nicht stabil, das sollten Sie beim Erstellen und Testen Ihrer Anwendung berücksichtigen. Sie werden mehrmals pro Jahr über Kanäle des Hostbetriebssystems auf allen unterstützten Plattformen aktualisiert. Diese Daten werden in der Regel nicht mit der Runtime verteilt.

Bewährte Methoden für die Lokalisierung

  1. Verschieben Sie alle lokalisierbaren Ressourcen in DLLs, die nur für Ressourcen vorgesehen sind. Lokalisierbare Ressourcen sind Benutzeroberflächenelemente, z. B. Zeichenfolgen, Fehlermeldungen, Dialogfelder, Menüs und eingebettete Objektressourcen.

  2. Zeichenfolgen und Benutzeroberflächenressourcen dürfen nicht hart codiert werden.

  3. Speichern Sie in den DLLs, die nur für Ressourcen vorgesehen sind, keine nicht lokalisierbaren Ressourcen. Das verwirrt die Übersetzer*innen.

  4. Verwenden Sie keine zusammengesetzten Zeichenfolgen, die während der Laufzeit aus verketteten Ausdrücken erstellt werden. Das Lokalisieren von zusammengesetzten Zeichenfolgen ist schwer, weil bei der Reihenfolge häufig von der englischen Grammatik ausgegangen wird, die in anderen Sprachen nicht zutrifft.

  5. Vermeiden Sie unklare Konstrukte wie "Empty Folder", in denen die Zeichenfolgen je nach grammatischen Rollen der Zeichenfolgenkomponenten unterschiedlich übersetzt werden können. "Empty" kann beispielsweise entweder ein Verb oder ein Adjektiv sein, d. h., das Konstrukt kann in Sprachen wie Deutsch, Italienisch oder Französisch unterschiedlich übersetzt werden.

  6. Vermeiden Sie in der Anwendung die Verwendung von Bildern und Symbolen, die Text enthalten. Das Lokalisieren dieser Texte ist teuer.

  7. Für die Erweiterung der Zeichenfolgen sollte auf der Benutzeroberfläche viel Platz vorhanden sein. In einigen Sprachen sind für manche Ausdrücke 50 bis 75 % mehr Platz als in anderen Sprachen erforderlich.

  8. Verwenden Sie die System.Resources.ResourceManager-Klasse, um Ressourcen basierend auf der Kultur abzurufen.

  9. Verwenden Sie Visual Studio zum Erstellen von Windows Forms-Dialogfeldern, sodass diese mit dem Windows Forms Resource Editor (Winres.exe) lokalisiert werden können. Windows Forms-Dialogfelder dürfen nicht manuell codiert werden.

  10. Es empfiehlt sich, eine professionelle Lokalisierung (Übersetzung) anfertigen zu lassen.

  11. Eine vollständige Beschreibung des Erstellens und Lokalisierens von Ressourcen finden Sie unter Ressourcen in .NET-Apps.

Bewährte Methoden bei der Globalisierung für ASP.NET und andere Serveranwendungen

Tipp

Die folgenden Best Practices gelten für ASP.NET Framework-Apps. Informationen zu ASP.NET Core-Apps finden Sie unter Globalisierung und Lokalisierung in ASP.NET Core.

  1. Legen Sie die CurrentUICulture-Eigenschaft und die CurrentCulture-Eigenschaft in der Anwendung explizit fest. Verlassen Sie sich nicht auf Standardwerte.

  2. Bei ASP.NET-Anwendungen handelt es sich um verwaltete Anwendungen, und sie können daher dieselben Klassen wie andere verwaltete Anwendungen zum Abrufen, Anzeigen und Bearbeiten von Informationen auf der Grundlage der Kultur verwenden.

  3. Sie können in ASP.NET die folgenden drei Codierungstypen angeben:

    • requestEncoding gibt die Codierung an, die der Clientbrowser empfängt.
    • responseEncoding gibt die Codierung an, die an den Clientbrowser gesendet wird. In den meisten Situationen sollte diese Codierung mit der für requestEncoding angegebenen identisch sein.
    • fileEncoding gibt die Standardcodierung für die Analyse von ASPX-, ASMX- und ASAX-Dateien an.
  4. Geben Sie die Werte für die Attribute requestEncoding, responseEncoding, fileEncoding, culture und uiCulture an folgenden drei Stellen in der ASP.NET-Anwendung an:

    • Im Globalisierungsabschnitt einer Web.config-Datei. Diese Datei befindet sich außerhalb der ASP.NET-Anwendung. Weitere Informationen finden Sie unter <globalization>-Element.
    • In einer Seitendirektive. Wenn sich eine Anwendung auf einer Seite befindet, wurde die Datei bereits gelesen. Daher können für fileEncoding und requestEncoding keine Werte mehr festgesetzt werden. Nur uiCulture, culture, und responseEncoding können in einer Seitenanweisung angegeben werden.
    • Programmgesteuert im Anwendungscode. Diese Einstellung kann auf Anforderung geändert werden. Wie bei der Seitenanweisung ist es bei Erreichen des Anwendungscodes bereits zu spät für die Festlegung von Werten für fileEncoding und requestEncoding. Nur uiCulture, culture, und responseEncoding können im Anwendungscode angegeben werden.
  5. Der uiCulture-Wert kann auf die vom Browser akzeptierte Sprache festgelegt werden.

  6. Für Anwendungen, die verteilt werden sollen, lassen Sie Updates ohne Downtime zu (z. B. Azure Container Apps). Entsprechend müssen Sie Situationen einplanen, in denen es möglicherweise mehrere Instanzen der Anwendung mit unterschiedlichen Formatregeln oder Kulturdaten gibt, in der Regel betrifft dies Zeitzonenregeln.

    • Wenn Ihre Anwendungsbereitstellung eine Datenbank umfasst, sollten Sie daran denken, dass die Datenbank über eigene Globalisierungsregeln verfügt. In den meisten Fällen sollten Sie keine globalisierungsbezogenen Funktionen direkt in der Datenbank ausführen.
    • Wenn Ihre Anwendungsbereitstellung eine Clientanwendung oder ein Web-Front-End mit Ressourcen für die Clientglobalisierung enthält, müssen Sie davon ausgehen, dass sich die Clientressourcen von den Ressourcen unterscheiden, die auf Ihrem Server verfügbar sind. Erwägen Sie, Globalisierungsfunktionen ausschließlich auf dem Client auszuführen.

Empfehlungen für stabile Tests

  1. Um Abhängigkeiten expliziter und Tests einfacher und parallelisierbarer zu machen, sollten Sie in Erwägung ziehen, kulturrelevante Einstellungen wie den CultureInfo-Parameter explizit an Methoden zu übergeben, die Formatierungen ausführen, und TimeZoneInfo an Methoden, die mit Datums- und Uhrzeitwerten arbeiten. Sie sollten außerdem beim Abrufen der Uhrzeit TimeProvider oder einen ähnlichen Typ verwenden.

  2. Bei den meisten Tests sollten Sie nicht explizit die genaue Ausgabe eines bestimmten Formatierungsvorgangs oder den genauen Offset einer Zeitzone überprüfen. Formatierungs- und Zeitzonendaten können sich jederzeit ändern und sich bei zwei ansonsten identischen Instanzen eines Betriebssystems (und möglicherweise sogar bei unterschiedlichen Prozessen auf demselben Computer) unterscheiden. Die Verwendung eines genauen Werts macht Tests kompliziert.

    • Im Allgemeinen reicht es aus zu überprüfen, ob eine Ausgaben empfangen wurde (z. B. nicht leere Zeichenfolgen beim Formatieren).
    • Bei einigen Datenelementen und -formaten können Sie stattdessen überprüfen, ob die Daten im Eingabewert geparst werden (Roundtripping). In Fällen, in denen Felder verworfen werden (z. B. das Jahr bei bestimmten datumsbezogenen Feldern) oder der Wert abgeschnitten oder gerundet wird (z. B. für die Gleitkommaausgabe), ist besondere Vorsicht geboten.
    • Wenn Sie explizite Anforderungen zum Überprüfen aller lokalisierten Formatausgabe haben, sollten Sie in Erwägung ziehen, bei der Testeinrichtung eine benutzerdefinierte Kultur zu erstellen und diese zu verwenden. In den meisten einfachen Fällen kann dies durch Instanziieren eines CultureInfo-Objekts mit dem new CultureInfo(..)-Konstruktor und Festlegen der Eigenschaften DateTimeFormat und NumberFormat erfolgen. Bei komplizierteren Fällen ermöglicht die Erstellung einer Unterklasse des Typs das Überschreiben weiterer Eigenschaften. Dies bietet möglicherweise noch weitere Vorteile, da Sie z. B. eine Pseudolokalisierung mit Ressourcendateien aktivieren können.
    • Wenn es explizit erforderlich ist, die Ergebnisse aller DateTime-Vorgänge zu überprüfen, sollten Sie in Erwägung ziehen, bei der Testeinrichtung eine benutzerdefinierte TimeZoneInfo-Instanz zu erstellen und diese zu verwenden. Dies bietet möglicherweise noch weitere Vorteile, da Sie z. B. stabile Tests bestimmter Sonderfälle (z. B. auf Änderungen an DST-Regeln) aktivieren können.

Weitere Informationen