Prácticas recomendadas para desarrollar aplicaciones de uso internacional

En esta sección se describen las procedimientos recomendados que hay que seguir al desarrollar aplicaciones de uso internacional.

Prácticas recomendadas de globalización

  1. Haga que la aplicación sea Unicode internamente.

  2. Utilice las clases que tienen en cuenta la referencia cultural proporcionadas por el espacio de nombres System.Globalization para manipular y aplicar formato a los datos.

    • Para ordenar, utilice las clases SortKey y CompareInfo.
    • Para las comparaciones de cadenas, utilice la clase CompareInfo.
    • Para el formato de fecha y hora, utilice la clase DateTimeFormatInfo.
    • Para aplicar formato numérico, utilice la claseNumberFormatInfo.
    • Para los calendarios gregorianos y los no gregorianos, use la clase Calendar o alguna de las implementaciones de calendario específicas.
  3. Utilice las configuraciones de propiedades de las referencias culturales proporcionadas por la clase System.Globalization.CultureInfo en las situaciones apropiadas. Utilice la propiedad CultureInfo.CurrentCulture para tareas de aplicación de formato, como aplicar formato de fecha y hora, o formato numérico. Para recuperar recursos, utilice la propiedad CultureInfo.CurrentUICulture. Tenga en cuenta que las propiedades CurrentCulture y CurrentUICulture se pueden establecer para cada subproceso.

  4. Habilite la aplicación para que lea y escriba datos a y desde diversas codificaciones mediante las clases de codificación del espacio de nombres System.Text. No suponga que los datos son ASCII. Dé por supuesto que se proporcionarán caracteres internacionales en cualquier parte donde el usuario pueda especificar texto. Por ejemplo, la aplicación debe aceptar caracteres internacionales en los nombres de servidores, directorios, nombres de archivo, nombres de usuario y direcciones URL.

  5. Cuando use la clase UTF8Encoding, por razones de seguridad, utilice la característica de detección de errores que ofrece esta clase. Para activar esta característica, cree una instancia de la clase mediante un constructor que tome el parámetro throwOnInvalidBytes y establezca su valor en true.

  6. Cuando sea posible, trate las cadenas como cadenas enteras en lugar de como una serie de caracteres individuales. Esto es especialmente importante al ordenar o buscar subcadenas. De esta forma evitará problemas asociados con el análisis de caracteres combinados. También puede trabajar con unidades de texto en lugar de caracteres individuales mediante la clase System.Globalization.StringInfo.

  7. Muestre texto utilizando las clases proporcionadas por el espacio de nombres System.Drawing.

  8. Por coherencia entre los sistemas operativos, no permita que la configuración de usuario invalide CultureInfo. Use el constructor CultureInfo que acepte un parámetro useUserOverride y establezca su valor en false.

  9. Pruebe la funcionalidad de la aplicación en versiones internacionales del sistema operativo usando datos internacionales.

  10. Si una decisión en materia de seguridad se basa en el resultado de una comparación de cadenas o un cambio en el uso de mayúsculas y minúsculas, use una operación de cadenas que no tenga en cuenta la referencia cultural. De este modo, se garantiza que el resultado no se ve afectado por el valor de CultureInfo.CurrentCulture. Vea la sección Comparaciones de cadenas que usan la referencia cultural actual de Prácticas recomendadas para utilizar las cadenas para obtener un ejemplo de cómo las comparaciones de cadenas que tienen en cuenta la referencia cultural pueden generar resultados incoherentes.

  11. Para cualquier elemento que se utilice para el intercambio (por ejemplo, un campo de un documento JSON en una llamada API) o el almacenamiento, use CultureInfo; además, debe especificar explícitamente un formato de ida y vuelta (como el especificador de formato de fecha y hora"O", "o"). Aunque las cadenas de formato de la referencia cultural invariable son estables y es poco probable que cambien, especificar una cadena de formato explícita ayuda a aclarar la intención del código.

  12. Los datos de globalización no son estables, algo que debe tener en cuenta a la hora de escribir la aplicación y sus pruebas. Se actualizan varias veces al año a través de los canales del sistema operativo host en todas las plataformas compatibles. Normalmente, estos datos no se distribuyen con el entorno de ejecución.

Prácticas recomendadas de localización

  1. Traslade todos los recursos localizables a archivos DLL independientes que sean sólo de recursos. Entre los recursos localizables se incluyen los elementos de la interfaz de usuario, como cadenas, mensajes de error, cuadros de diálogo, menús y recursos de objetos incrustados.

  2. No incluya en el código no modificable las cadenas o recursos de la interfaz de usuario.

  3. No incluya recursos no localizables en archivos DLL que sean solo de recursos. Esto confunde a los traductores.

  4. No utilice cadenas compuestas que se compilan en tiempo de ejecución a partir de frases concatenadas. La localización de las cadenas compuestas resulta difícil porque a menudo se da por supuesto un orden gramatical inglés que no se aplica a todos los idiomas.

  5. Evite construcciones ambiguas, como "Empty Folder", donde las cadenas se pueden traducir de forma diferente según los roles gramaticales de los componentes de las cadenas. Por ejemplo, "empty" puede ser tanto un verbo como un adjetivo, lo cual puede conducir a traducciones diferentes en idiomas como el italiano o el francés.

  6. Evite utilizar en la aplicación imágenes e iconos que contengan texto. Su localización es costosa.

  7. Prevea mucho espacio para expandir la longitud de las cadenas en la interfaz de usuario. En algunos idiomas, las frases pueden requerir entre un 50 y un 75 por ciento más de espacio que en otros idiomas.

  8. Utilice la clase System.Resources.ResourceManager para recuperar recursos en función de la referencia cultural.

  9. Use Visual Studio para crear cuadros de diálogo de Windows Forms, de manera que se puedan localizar mediante el Editor de recursos de Windows Forms (Winres.exe). No programe los cuadros de diálogo de Windows Forms manualmente.

  10. Organice una localización profesional (traducción).

  11. Para obtener una descripción completa de cómo crear y adaptar los recursos, consulte Recursos en aplicaciones .NET.

Procedimientos recomendados de globalización para aplicaciones de ASP.NET y otros servidores

Sugerencia

Los procedimientos recomendados siguientes son para aplicaciones de ASP.NET Framework. Para obtener la información relativa a las aplicaciones de ASP.NET Core, consulte Globalización y localización en ASP.NET Core.

  1. Establezca explícitamente las propiedades CurrentUICulture y CurrentCulture en su aplicación. No se base en valores predeterminados.

  2. Tenga en cuenta que las aplicaciones de ASP.NET son administradas y, por lo tanto, pueden utilizar las mismas clases que otras aplicaciones administradas para recuperar, mostrar y tratar información basada en la referencia cultural.

  3. Tenga presente que puede especificar los tres tipos siguientes de codificación en ASP.NET:

    • requestEncoding especifica la codificación que se recibe desde el explorador del cliente.
    • responseEncoding especifica la codificación que se envía al explorador del cliente. En la mayoría de los casos, esta codificación debe ser igual que la especificada para requestEncoding.
    • fileEncoding especifica la codificación predeterminada para el análisis de archivos .aspx, .asmx y .asax.
  4. Especifique los valores de los atributos requestEncoding, responseEncoding, fileEncoding, culture y uiCulture en los tres lugares siguientes de una aplicación de ASP.NET:

    • En la sección de globalización de un archivo Web.config. Este archivo es externo a la aplicación de ASP.NET. Para obtener más información, consulte Elemento <globalization>.
    • En una directiva de página. Tenga en cuenta que, cuando una aplicación está en una página, el archivo ya se ha leído. Por lo tanto, es demasiado tarde para especificar fileEncoding y requestEncoding. En una directiva de página solo se puede especificar uiCulture, culture y responseEncoding.
    • Mediante programación en el código de la aplicación. Esta configuración puede cambiarse para cada solicitud. Como con la directiva de página, cuando se llega al código de la aplicación es demasiado tarde para especificar fileEncoding y requestEncoding. En el código de la aplicación solo se puede especificar uiCulture, culture y responseEncoding.
  5. Tenga en cuenta que el valor de uiCulture puede establecerse en el idioma aceptado por el explorador.

  6. En el caso de las aplicaciones distribuidas, permita actualizaciones sin tiempo de inactividad (por ejemplo, de Azure Container Apps); en ocasiones, también debe planear situaciones en las que pueda haber varias instancias de la aplicación con distintas reglas de formato u otros datos de referencias culturales, sobre todo reglas de zona horaria.

    • Si la implementación de la aplicación incluye una base de datos, recuerde que esta última tendrá sus propias reglas de globalización. En la mayoría de los casos, debe evitar realizar funciones relacionadas con la globalización en la base de datos.
    • Si la implementación de la aplicación incluye una aplicación cliente o un front-end web que usan recursos de globalización de cliente, asuma que los recursos de cliente difieren de los recursos disponibles para el servidor. Considere la posibilidad de realizar exclusivamente funciones de globalización en el cliente.

Recomendaciones para pruebas sólidas

  1. Para que las dependencias sean más explícitas y las pruebas sean potencialmente más fáciles y se puedan realizar en paralelo, debe considerar la posibilidad de pasar explícitamente la configuración relevante para la referencia cultural, como los parámetros CultureInfo, a los métodos que aplican formato y TimeZoneInfo a los métodos que trabajan con fechas y horas. También debe usar TimeProvider o un tipo similar al recuperar la hora.

  2. Para la mayoría de las pruebas, no debe validar explícitamente la salida exacta de una operación de formato determinada ni el desplazamiento exacto de una zona horaria. Los datos de formato y de zona horaria pueden cambiar en cualquier momento y diferir entre dos instancias por lo demás idénticas de un sistema operativo (y procesos potencialmente distintos en la misma máquina). Basarse en un valor exacto hace que las pruebas sean frágiles.

    • Por lo general, será suficiente validar que se ha recibido alguna salida (por ejemplo, cadenas no vacías al aplicar formato).
    • Para algunos formatos y elementos de datos, se puede validar en su lugar que los datos analicen el valor de entrada (ida y vuelta). Debe tenerse cuidado en los casos en los que se quitan campos (por ejemplo, el año en algunos campos relacionados con la fecha) o el valor se trunca o se redondea (por ejemplo, para la salida de punto flotante).
    • Si tiene requisitos explícitos para validar toda la salida de formato localizada, debe considerar la posibilidad de crear y usar una referencia cultural personalizada durante la configuración de la prueba. En los casos más simples, esto se puede hacer mediante la creación de instancias de un objeto CultureInfo con su constructor new CultureInfo(..) y el establecimiento de las propiedades DateTimeFormat y NumberFormat. En los casos más complicados, la creación de subclases del tipo permite invalidar las propiedades adicionales. Esto tiene posibles ventajas adicionales, como habilitar la pseudolocalización con los archivos de recursos.
    • Si tiene requisitos explícitos para validar los resultados de todas las operaciones de fecha y hora, debe considerar la posibilidad de crear y usar una instancia de TimeZoneInfo personalizada durante la configuración de la prueba. Esto tiene posibles ventajas adicionales, como habilitar pruebas estables de determinados casos perimetrales (por ejemplo, cambios en las reglas de DST).

Consulte también