Meilleures pratiques pour développer des applications internationales

Cette section décrit les meilleures pratiques pour développer des applications mondialisables.

Meilleures pratiques de globalisation

  1. Utilisez le codage Unicode en interne dans votre application.

  2. Servez-vous des classes fournies par l'espace de noms System.Globalization pour manipuler les données et les mettre en forme.

    • Pour trier, utilisez la classe SortKey et la classe CompareInfo.
    • Pour les comparaisons de chaînes, utilisez la classe CompareInfo.
    • Pour la mise en forme des dates et heures, utilisez la classe DateTimeFormatInfo.
    • Pour la mise en forme des nombres, utilisez la classe NumberFormatInfo.
    • Pour les calendriers grégoriens et non grégoriens, utilisez la classe Calendar ou l'une des implémentations de calendrier spécifiques.
  3. Utilisez les paramètres de propriété de culture fournis par la classe System.Globalization.CultureInfo dans les situations appropriées. Utilisez la propriété CultureInfo.CurrentCulture pour les tâches de mise en forme, par exemple la mise en forme des dates, des heures ou des nombres. Utilisez la propriété CultureInfo.CurrentUICulture pour récupérer des ressources. Notez que les propriétés CurrentCulture et CurrentUICulture peuvent être définies par thread.

  4. Permettez à votre application de lire et d'écrire des données dans divers systèmes d'encodage à l'aide des classes d'encodage de l'espace de noms System.Text. Ne supposez pas que les données entrées dans votre application seront par défaut codées en ASCII. Supposez que des caractères internationaux seront fournis partout où un utilisateur peut entrer un texte. Par exemple, l'application doit accepter les caractères internationaux dans les noms de serveurs, de répertoires, de fichiers et d'utilisateurs, ainsi que dans les URL.

  5. Lorsque vous utilisez la classe UTF8Encoding, pour des raisons de sécurité, utilisez la fonctionnalité de détection d’erreurs offerte par cette classe. Pour activer la fonctionnalité de détection d’erreurs, créez une instance de la classe à l’aide du constructeur qui prend un paramètre throwOnInvalidBytes et affectez-lui la valeur true.

  6. Autant que possible, traitez les chaînes comme des chaînes entières, et non comme une série de caractères. Ceci est particulièrement important lorsque vous effectuez un tri ou que vous recherchez des sous-chaînes. Vous éviterez ainsi les problèmes liés à l'analyse de caractères combinés. Vous pouvez aussi utiliser des unités de texte au lieu de caractères uniques avec la classe System.Globalization.StringInfo.

  7. Affichez le texte à l'aide des classes fournies par l'espace de noms System.Drawing.

  8. Pour préserver la cohérence parmi les divers systèmes d'exploitation, ne permettez pas aux paramètres utilisateur de se substituer à CultureInfo. Utilisez le constructeur CultureInfo qui accepte un paramètre useUserOverride et lui affecte la valeur false.

  9. Testez les fonctionnalités de votre application sur des versions internationales des systèmes d'exploitation, en utilisant des données internationales.

  10. Si une décision relative à la sécurité est basée sur le résultat d’une opération de comparaison de chaînes ou de changement de casse, utilisez une opération de chaînes indépendante de la culture. Cette pratique garantit que le résultat n'est pas affecté par la valeur de CultureInfo.CurrentCulture. Consultez la section « Comparaisons de chaînes qui utilisent la culture actuelle » du document Bonnes pratiques pour l’utilisation de chaînes pour voir un exemple montrant comment les comparaisons de chaînes dépendantes de la culture peuvent produire des résultats incohérents.

  11. Pour tout élément utilisé pour l’échange (par exemple, un champ dans un document JSON dans un appel d’API) ou le stockage, veuillez utiliser CultureInfo. En outre, vous devez explicitement spécifier un format aller-retour (par exemple, le "O", "o"le spécificateur du format de date e d’heure). Bien que les chaînes de format pour la culture invariante soient stables et peu susceptibles de changer, la spécification explicite d’une chaîne de format permet de clarifier l’intention de votre code.

  12. Les données de globalisation ne sont pas stables et vous devez écrire votre application et ses tests en tenant compte de cela. Elles sont mises à jour plusieurs fois par an via des canaux de système d’exploitation hôtes sur toutes les plateformes prises en charge. Ces données ne sont généralement pas distribuées avec le runtime.

Meilleures pratiques de localisation

  1. Déplacez toutes les ressources localisables vers des bibliothèques DLL séparées, consacrées exclusivement à ces ressources. Les ressources localisables incluent les éléments d'interface utilisateur, tels que les chaînes, les messages d'erreur, les boîtes de dialogue et les menus, ainsi que les ressources d'objet incorporé.

  2. Ne codez pas en dur les chaînes ou les ressources d'interface utilisateur.

  3. Ne placez pas de ressources non localisables dans les DLL consacrées exclusivement aux ressources. Cela entraîne une confusion pour les traducteurs.

  4. N'utilisez pas de chaînes composites qui sont construites au moment de l'exécution à partir d'expressions concaténées. Les chaînes composites sont difficiles à localiser parce qu'elles supposent souvent un ordre grammatical anglais qui ne s'applique pas à toutes les langues.

  5. Évitez les constructions ambigües telles que « Empty Folder », dans lesquelles les chaînes peuvent être traduites différemment selon les rôles grammaticaux de leurs composants. Par exemple, « empty » peut être un verbe ou un adjectif, ce qui conduit à des traductions différentes dans des langues telles que l'italien ou le français.

  6. Évitez d'utiliser des images et des icônes qui contiennent du texte dans votre application. Le coût de leur localisation est élevé.

  7. Prévoyez beaucoup de place pour la longueur des chaînes à développer dans l’interface utilisateur. Dans certaines langues, les phrases sont de 50 à 75 % plus longues que dans d'autres.

  8. Utilisez la classe System.Resources.ResourceManager pour récupérer des ressources selon culture.

  9. Utilisez Visual Studio pour créer des boîtes de dialogue Windows Forms, que vous pourrez localiser à l’aide de l’Éditeur de ressources Windows Forms (Winres.exe). Ne codez pas les boîtes de dialogue Windows Forms manuellement.

  10. Confiez la localisation (la traduction) à des professionnels.

  11. Pour obtenir une description complète de la création et de la localisation des ressources, consultez Ressources dans les applications .NET.

Meilleures pratiques de globalisation pour ASP.NET et d’autres applications serveur

Conseil

Les meilleures pratiques suivantes concernent les applications ASP.NET Framework. Pour les applications ASP.NET Core, consultez Globalisation et localisation dans ASP.NET Core.

  1. Définissez explicitement les propriétés CurrentUICulture et CurrentCulture dans vote application. Ne comptez pas sur leurs valeurs par défaut.

  2. Notez que les applications ASP.NET sont des applications managées et, par conséquent, peuvent utiliser les mêmes classes que d'autres applications managées pour récupérer, afficher et manipuler des informations en fonction de la culture.

  3. Gardez à l'esprit que vous pouvez spécifier les trois types d'encodage suivants dans ASP.NET :

    • requestEncoding spécifie l’encodage reçu du navigateur du client.
    • responseEncoding spécifie l’encodage à envoyer au navigateur du client. Dans la plupart des situations, cet encodage doit être identique à celui spécifié pour requestEncoding.
    • fileEncoding spécifie l’encodage par défaut pour l’analyse des fichiers .aspx, .asmx et .asax.
  4. Spécifiez les valeurs des attributs requestEncoding, responseEncoding, fileEncoding, culture et uiCulture dans les trois emplacements suivants dans une application ASP.NET :

    • Dans la section globalisation d’un fichier Web.config. Ce fichier est externe à l'application ASP.NET. Pour plus d'informations, consultez la page élément <globalization>.
    • Dans une directive de page. Notez que lorsqu'une application se trouve dans une page, le fichier a déjà été lu. De ce fait, il est trop tard pour spécifier fileEncoding et requestEncoding. Seuls les attributs uiCulture, culture et responseEncoding peuvent être spécifiés dans une directive de page.
    • Par programme, dans le code de l'application. Ce paramètre peut varier par demande. Comme pour la directive de page, il est trop tard pour spécifier fileEncoding et requestEncoding quand le code de l’application est atteint. Seuls les attributs uiCulture, culture et responseEncoding peuvent être spécifiés dans le code de l’application.
  5. Notez que la valeur uiCulture peut être définie sur la langue acceptée par le navigateur.

  6. Pour les applications distribuées, veuillez autoriser les mises à jour sans temps d’arrêt (par exemple, Azure Container Apps) ou pour des situations similaires, dans lesquelles il peut y avoir plusieurs instances de l’application avec différentes règles de format ou d’autres données de culture, ainsi que les règles de fuseau horaire les plus pertinentes.

    • Si votre déploiement d’application inclut une base de données, n’oubliez pas que celle-ci aura ses propres règles de globalisation. Dans la plupart des cas, vous devez éviter d’exécuter des fonctions liées à la globalisation dans la base de données.
    • Si votre déploiement d’application inclut une application cliente ou un front-end web à l’aide de ressources de globalisation du client, partez du principe que les ressources clientes diffèrent des ressources disponibles pour votre serveur. Envisagez d’exécuter exclusivement des fonctions de globalisation sur le client.

Recommandations pour les tests robustes

  1. Pour rendre les dépendances plus explicites et les tests potentiellement plus faciles et parallélisables, vous devez envisager de transmettre explicitement des réglages pertinents à la culture, tels que des paramètres CultureInfo, aux méthodes qui effectuent la mise en forme et TimeZoneInfo aux méthodes qui fonctionnent avec des dates et des heures. Vous devez également utiliser TimeProvider ou un type similaire lors de la récupération de l’heure.

  2. Pour la plupart des tests, vous ne devez pas valider explicitement la sortie exacte d’une opération de mise en forme donnée ou le décalage exact d’un fuseau horaire. La mise en forme et les données de fuseau horaire peuvent changer à tout moment et différer entre deux instances identiques d’un système d’exploitation (et potentiellement différents processus sur le même ordinateur). S’appuyer sur une valeur exacte fragilise les tests.

    • En règle générale, la validation de la réception d’une sortie est suffisante (par exemple, les chaînes non vides lors de la mise en forme).
    • Pour certains éléments et formats de données, la validation de la valeur d’entrée peut être utilisée à la place (aller-retour). Vous devez veiller à ce que les champs soient supprimés (par exemple, année pour certains champs liés à la date) ou à ce que la valeur soit tronquée ou arrondie (par exemple, pour une valeur à virgule flottante).
    • Si vous avez des exigences explicites pour valider toutes les sorties de format localisées, vous devez envisager de créer et d’utiliser une culture personnalisée lors de la configuration du test. Pour la plupart des cas simples, cela peut être effectué en instanciant un objet CultureInfo avec son constructeur new CultureInfo(..) et en définissant les propriétés DateTimeFormat et NumberFormat. Pour les cas plus compliqués, la sous-classe du type permet de remplacer des propriétés supplémentaires. Il existe des avantages supplémentaires potentiels à ceci, tels que l’activation de la pseudo-localisation avec des fichiers de ressources.
    • Si vous avez des exigences explicites pour valider les résultats de toutes les opérations de date/heure, vous devez envisager de créer et d’utiliser une instance personnalisée TimeZoneInfo pendant l’initialisation du test. Il existe des avantages supplémentaires à cela, tels que l’activation de tests stables de certains cas de périphérie (par exemple, les modifications apportées aux règles DST).

Voir aussi