Najlepsze rozwiązania dotyczące tworzenia aplikacji gotowych do użycia na świecie
W tej sekcji opisano najlepsze rozwiązania, które należy zastosować podczas tworzenia aplikacji gotowych do użycia na świecie.
Najlepsze rozwiązania dotyczące globalizacji
Utwórz aplikację w formacie Unicode wewnętrznie.
Użyj klas obsługujących kulturę udostępnianych przez System.Globalization przestrzeń nazw, aby manipulować danymi i formatować je.
- Do sortowania SortKey użyj klasy i CompareInfo klasy .
- W przypadku porównań ciągów użyj CompareInfo klasy .
- W przypadku formatowania daty i godziny użyj DateTimeFormatInfo klasy .
- W przypadku formatowania liczbowego użyj NumberFormatInfo klasy .
- W przypadku kalendarzy gregoriańskich i innych niż gregoriański użyj Calendar klasy lub jednej z określonych implementacji kalendarza.
Użyj ustawień właściwości kultury udostępnianych przez klasę System.Globalization.CultureInfo w odpowiednich sytuacjach. CultureInfo.CurrentCulture Użyj właściwości do formatowania zadań, takich jak data i godzina lub formatowanie liczbowe. CultureInfo.CurrentUICulture Użyj właściwości , aby pobrać zasoby. Należy pamiętać, że
CurrentCulture
właściwości iCurrentUICulture
można ustawić na wątek.Umożliwia aplikacji odczytywanie i zapisywanie danych do i z różnych kodowań przy użyciu klas kodowania w System.Text przestrzeni nazw. Nie zakładaj danych ASCII. Załóżmy, że znaki międzynarodowe będą dostarczane w dowolnym miejscu, w jakim użytkownik może wprowadzić tekst. Na przykład aplikacja powinna akceptować znaki międzynarodowe w nazwach serwerów, katalogach, nazwach plików, nazwach użytkowników i adresach URL.
W przypadku korzystania z klasy ze względów bezpieczeństwa należy użyć UTF8Encoding funkcji wykrywania błędów oferowanej przez tę klasę. Aby włączyć funkcję wykrywania błędów, utwórz wystąpienie klasy przy użyciu konstruktora, który przyjmuje
throwOnInvalidBytes
parametr i ustaw wartość tego parametru natrue
.Jeśli to możliwe, obsłuż ciągi jako całe ciągi, a nie jako serię pojedynczych znaków. Jest to szczególnie ważne podczas sortowania lub wyszukiwania podciągów. Zapobiegnie to problemom związanym z analizowaniem połączonych znaków. Możesz również pracować z jednostkami tekstu, a nie pojedynczymi znakami przy użyciu System.Globalization.StringInfo klasy .
Wyświetlaj tekst przy użyciu klas udostępnianych przez System.Drawing przestrzeń nazw.
Aby zapewnić spójność w różnych systemach operacyjnych, nie zezwalaj na zastępowanie CultureInfoustawień użytkownika. Użyj konstruktora
CultureInfo
, który akceptujeuseUserOverride
parametr i ustaw go nafalse
wartość .Przetestuj funkcje aplikacji w międzynarodowych wersjach systemu operacyjnego przy użyciu danych międzynarodowych.
Jeśli decyzja dotycząca zabezpieczeń jest oparta na wyniku operacji porównywania ciągów lub zmiany wielkości liter, użyj operacji ciągu bez uwzględniania kultury. Ta praktyka gwarantuje, że wynik nie ma wpływu na wartość
CultureInfo.CurrentCulture
. Zobacz sekcję "Porównania ciągów, które używają bieżącej kultury" w sekcji Najlepsze rozwiązania dotyczące używania ciągów, aby zapoznać się z przykładem, w którym pokazano, jak porównania ciągów wrażliwych na kulturę mogą generować niespójne wyniki.W przypadku każdego elementu używanego do wymiany (na przykład pola w dokumencie JSON w wywołaniu interfejsu API) lub magazynu należy CultureInfojawnie określić format dwukierunkowy (taki jak
"o"
"O"
specyfikator formatu daty i godziny). Chociaż ciągi formatu dla niezmiennej kultury są stabilne i mało prawdopodobne do zmiany, określenie jawnego ciągu formatu pomaga wyjaśnić intencję kodu.- W przypadku elementów daty/godziny należy wziąć pod uwagę porady i obserwacje autora Noda Time Jon Skeet, który dzieli się cennymi szczegółowymi informacjami. Aby uzyskać więcej informacji, zobacz Jon Skeet: Storing UTC nie jest srebrnym punktorem.
Dane globalizacji nie są stabilne i należy napisać aplikację i jej testy, mając to na uwadze. Jest on aktualizowany kilka razy w roku za pośrednictwem kanałów systemu operacyjnego hosta na wszystkich obsługiwanych platformach. Te dane zwykle nie są dystrybuowane ze środowiskiem uruchomieniowym.
Najlepsze rozwiązania dotyczące lokalizacji
Przenieś wszystkie zasoby lokalizowalne do oddzielnych bibliotek DLL tylko dla zasobów. Zasoby lokalizowalne obejmują elementy interfejsu użytkownika, takie jak ciągi, komunikaty o błędach, okna dialogowe, menu i zasoby obiektów osadzonych.
Nie należy kodować ciągów twardych ani zasobów interfejsu użytkownika.
Nie umieszczaj zasobów nielokalizacyjnych w bibliotekach DLL tylko dla zasobów. To mylą tłumacze.
Nie używaj ciągów złożonych utworzonych w czasie wykonywania z połączonych fraz. Ciągi złożone są trudne do zlokalizowania, ponieważ często zakładają one angielski porządek gramatyczny, który nie ma zastosowania do wszystkich języków.
Unikaj niejednoznacznych konstrukcji, takich jak "Pusty folder", gdzie ciągi mogą być tłumaczone inaczej w zależności od ról gramatycznych składników ciągu. Na przykład "pusty" może być czasownikiem lub przymiotnikiem, co może prowadzić do różnych tłumaczeń w językach, takich jak włoski lub francuski.
Unikaj używania obrazów i ikon zawierających tekst w aplikacji. Są one kosztowne do lokalizowania.
Umożliwia dużą ilość miejsca na rozwinięcie długości ciągów w interfejsie użytkownika. W niektórych językach frazy mogą wymagać 50–75 procent więcej miejsca niż w innych językach.
System.Resources.ResourceManager Użyj klasy , aby pobrać zasoby na podstawie kultury.
Użyj programu Visual Studio , aby utworzyć okna dialogowe formularzy systemu Windows, aby można je było lokalizować przy użyciu Edytora zasobów formularzy systemu Windows (Winres.exe). Nie koduj okien dialogowych Windows Forms ręcznie.
Rozmieść profesjonalną lokalizację (tłumaczenie).
Aby uzyskać pełny opis tworzenia i lokalizowania zasobów, zobacz Zasoby w aplikacjach platformy .NET.
Najlepsze rozwiązania dotyczące globalizacji dla ASP.NET i innych aplikacji serwerowych
Napiwek
Poniższe najlepsze rozwiązania dotyczą aplikacji platformy ASP.NET Framework. Aby zapoznać się z aplikacjami ASP.NET Core, zobacz Globalizacja i lokalizacja w programie ASP.NET Core.
Jawne ustawianie CurrentUICulture właściwości i CurrentCulture w aplikacji. Nie należy polegać na wartościach domyślnych.
Należy pamiętać, że aplikacje ASP.NET są aplikacjami zarządzanymi i dlatego mogą używać tych samych klas co inne aplikacje zarządzane do pobierania, wyświetlania i manipulowania informacjami na podstawie kultury.
Należy pamiętać, że można określić następujące trzy typy kodowań w ASP.NET:
requestEncoding
określa kodowanie odebrane z przeglądarki klienta.responseEncoding
określa kodowanie do wysyłania do przeglądarki klienta. W większości sytuacji kodowanie powinno być takie samo jak określone dla elementurequestEncoding
.- fileEncoding określa domyślne kodowanie dla .aspx, asmx i .asax analizowania plików.
Określ wartości atrybutów
requestEncoding
, ,responseEncoding
fileEncoding
,culture
iuiCulture
w następujących trzech miejscach w aplikacji ASP.NET:- W sekcji globalizacji pliku Web.config . Ten plik jest zewnętrzny dla aplikacji ASP.NET. Aby uzyskać więcej informacji, zobacz <element globalizacji>.
- W dyrektywie strony. Należy pamiętać, że gdy aplikacja znajduje się na stronie, plik został już odczytany. W związku z tym jest za późno, aby określić plikEncoding i requestEncoding. Tylko
uiCulture
,culture
iresponseEncoding
można określić w dyrektywie page. - Programowo w kodzie aplikacji. To ustawienie może się różnić w zależności od żądania. Podobnie jak w przypadku dyrektywy page, po osiągnięciu kodu aplikacji jest za późno, aby określić
fileEncoding
irequestEncoding
. W kodzie aplikacji można określić tylkouiCulture
,culture
iresponseEncoding
.
Należy pamiętać, że wartość uiCulture można ustawić na język akceptowania przez przeglądarkę.
W przypadku aplikacji, które są rozproszone, zezwalaj na aktualizacje bez przestojów (na przykład Azure Container Apps) lub podobne, należy zaplanować sytuacje, w których może istnieć wiele wystąpień aplikacji z różnymi regułami formatu lub innymi danymi kultury, co jest najbardziej istotne dla reguł strefy czasowej.
- Jeśli wdrożenie aplikacji obejmuje bazę danych, pamiętaj, że baza danych będzie miała własne reguły globalizacji. W większości przypadków należy unikać wykonywania wszelkich funkcji związanych z globalizacją w bazie danych.
- Jeśli wdrożenie aplikacji obejmuje aplikację kliencką lub fronton internetowy przy użyciu zasobów globalizacji klienta, załóżmy, że zasoby klienckie różnią się od zasobów dostępnych dla serwera. Rozważ wyłącznie wykonywanie funkcji globalizacji na kliencie.
Rekomendacje na potrzeby niezawodnego testowania
Aby zwiększyć jawne zależności i testowanie potencjalnie łatwiejsze i zrównalne, należy rozważyć jawne przekazanie ustawień związanych z kulturą, takich jak
CultureInfo
parametry, do metod, które wykonują formatowanie, orazTimeZoneInfo
do metod, które współpracują z datami i godzinami. Należy również użyć TimeProvider lub podobnego typu podczas pobierania czasu.W przypadku większości testów nie należy jawnie weryfikować dokładnych danych wyjściowych danej operacji formatowania ani dokładnego przesunięcia strefy czasowej. Formatowanie i dane strefy czasowej mogą ulec zmianie w dowolnym momencie i mogą się różnić między dwoma inaczej identycznymi wystąpieniami systemu operacyjnego (i potencjalnie różnymi procesami na tym samym komputerze). Poleganie na dokładnej wartości sprawia, że testy są kruche.
- Ogólnie rzecz biorąc, sprawdzanie, czy niektóre dane wyjściowe zostały odebrane, będą wystarczające (na przykład niepuste ciągi podczas formatowania).
- W przypadku niektórych elementów danych i formatów sprawdzanie poprawności analizowania danych do wartości wejściowej może zamiast tego być używane (zaokrąglanie). Należy zachować ostrożność w przypadkach, w których pola są porzucane (na przykład rok dla niektórych pól związanych z datą) lub wartość obcięta lub zaokrąglona (np. dla danych wyjściowych zmiennoprzecinkowych).
- Jeśli masz jawne wymagania dotyczące weryfikowania wszystkich zlokalizowanych danych wyjściowych formatu, należy rozważyć utworzenie i użycie kultury niestandardowej podczas konfigurowania testu. W większości prostych przypadków można to zrobić, tworząc wystąpienie obiektu za pomocą konstruktora i ustawiając
CultureInfo
DateTimeFormat
właściwości iNumberFormat
.new CultureInfo(..)
W przypadku bardziej skomplikowanych przypadków podklasowanie typu umożliwia zastępowanie dodatkowych właściwości. Istnieją potencjalne dodatkowe korzyści, takie jak włączenie pseudolokalizacji z plikami zasobów. - Jeśli masz jawne wymagania dotyczące weryfikowania wyników wszystkich operacji daty/godziny, należy rozważyć utworzenie i użycie wystąpienia niestandardowego
TimeZoneInfo
podczas konfigurowania testu. Istnieją potencjalne dodatkowe korzyści, takie jak umożliwienie stabilnego testowania niektórych przypadków brzegowych (na przykład zmiany reguł DST).