Práticas recomendadas para o desenvolvimento de aplicativos preparados para globalização

Essa seção descreve as práticas recomendadas a serem seguidas no desenvolvimento de aplicativos prontos para o mundo.

Práticas recomendadas de globalização

  1. Crie o aplicativo Unicode internamente.

  2. Use as classes com reconhecimento de cultura fornecidas pelo namespace System.Globalization para manipular e formatar dados.

    • Para classificar, use a classe SortKey e a classe CompareInfo.
    • Para comparações de cadeia de caracteres, use a classe CompareInfo.
    • Para formatação de data e hora, use a classe DateTimeFormatInfo.
    • Para formatação numérica, use a classe NumberFormatInfo.
    • Para calendários gregoriano e não gregorianos, use a classe Calendar ou uma das implementações de calendário específicas.
  3. Em determinadas situações, use as configurações das propriedades de cultura fornecidas pela classe System.Globalization.CultureInfo. Use a propriedade CultureInfo.CurrentCulture para formatar tarefas, como a data e a hora, ou a formatação numérica. Use a propriedade CultureInfo.CurrentUICulture para recuperar recursos. Observe que as propriedades CurrentCulture e CurrentUICulture podem ser definidas por threads.

  4. Habilite seu aplicativo para ler e gravar dados em várias codificações usando as classes de codificação no namespace System.Text. Não aceite dados ASCII. Suponha que caracteres internacionais sejam fornecidos em todos os lugares que um usuário possa inserir texto. Por exemplo, o aplicativo deve aceitar caracteres internacionais em nomes de servidor, diretórios, nomes de arquivos, nomes de usuário e URLs.

  5. Ao usar a classe UTF8Encoding, por motivos de segurança, use o recurso de detecção de erros oferecido pela classe. Para ativar o recurso de detecção de erro, crie uma instância da classe usando o construtor que usa um parâmetro throwOnInvalidBytes e defina o valor desse parâmetro como true.

  6. Sempre que possível, trate as cadeias de caracteres como cadeias de caracteres inteiras em vez de tratá-las como uma série de caracteres individuais. Isso é especialmente importante durante a classificação ou a pesquisa de subcadeias de caracteres. Isso evitará problemas associados à análise de caracteres combinados. Você também pode trabalhar com unidades de texto em vez de com caracteres únicos usando a classe System.Globalization.StringInfo.

  7. Exiba o texto usando as classes fornecidas pelo namespace System.Drawing.

  8. Para ser consistente entre sistemas operacionais, não permita que as configurações de usuário substituam CultureInfo. Use o constructo CultureInfo que aceita um parâmetro useUserOverride e define-o como false.

  9. Teste a funcionalidade de seu aplicativo em versões de sistemas operacionais internacionais usando dados internacionais.

  10. Se uma decisão de segurança for baseada no resultado de uma comparação de cadeia de caracteres ou de uma operação de alteração entre maiúsculas e minúsculas, use uma operação de cadeia de caracteres sem detecção de cultura. Essa prática garante que o resultado não seja afetado pelo valor de CultureInfo.CurrentCulture. Confira a seção "Comparações de cadeia de caracteres que usam a cultura atual" das Práticas recomendadas para usar cadeias de caracteres para obter um exemplo que demonstra como as comparações de cadeias de caracteres com detecção de cultura podem produzir resultados inconsistentes.

  11. Para qualquer elemento que esteja sendo usado para intercâmbio (por exemplo, um campo em um documento JSON em uma chamada à API) ou armazenamento, use o CultureInfo; além disso, você deve especificar explicitamente um formato de ida e volta (como o especificador de formato de data e hora "O", "o"). Embora as cadeias de caracteres de formato para a invariável cultura sejam estáveis e improváveis de serem alteradas, especificar uma cadeia de caracteres de formato explícita ajuda a esclarecer a intenção do código.

  12. Os dados de globalização não são estáveis, e você deve escrever seu aplicativo e seus testes com isso em mente. Eles são atualizados várias vezes por ano por meio de canais de SO host em todas as plataformas com suporte. Normalmente, esses dados não são distribuídos com o runtime.

Práticas recomendadas de localização

  1. Mova todos os recursos localizáveis para separar DLLs somente de recursos. Os recursos localizáveis incluem elementos da interface do usuário, como cadeias de caracteres, mensagens de erro, caixas de diálogo, menus e recursos do objeto inserido.

  2. Não codifique cadeias de caracteres ou recursos da interface do usuário.

  3. Não coloque recursos não localizáveis em DLLs somente de recursos. Isso confunde os tradutores.

  4. Não use cadeias de caracteres compostas compiladas em tempo de execução de frases concatenadas. As cadeias de caracteres compostas são difíceis de localizar já que elas muitas vezes assumem uma ordem gramatical em inglês que não se aplica a todos os idiomas.

  5. Evite constructos ambíguos, como "Empty Folder" (Pasta vazia), em que as cadeias de caracteres podem ser traduzidas de forma diferente dependendo das funções gramaticais dos componentes da cadeia de caracteres. Por exemplo, "empty", em inglês, pode ser um verbo ou um adjetivo (esvaziar/vazio) e isso pode levar a diferentes traduções em idiomas como italiano ou francês.

  6. No aplicativo, evite usar imagens e ícones que contenham texto. Fica caro localizá-los.

  7. Dê espaço suficiente ao comprimento das cadeias de caracteres para que elas possam se expandir na interface do usuário. Em alguns idiomas, as frases podem exigir de 50 a 75% mais espaço do que em outros idiomas.

  8. Use a classe System.Resources.ResourceManager para recuperar os recursos com base na cultura.

  9. Use o Visual Studio para criar caixas de diálogo do Windows Forms para que elas possam ser localizadas usando o Editor de Recursos do Windows Forms (Winres.exe). Não codifique manualmente as caixas de diálogo do Windows Forms.

  10. Procure um profissional de localização (tradução).

  11. Para obter uma descrição completa sobre a criação e a localização de recursos, confira Recursos em aplicativos do .NET.

Melhores práticas de globalização para ASP.NET e outros aplicativos de servidor

Dica

As melhores práticas a seguir são para aplicativos ASP.NET Framework. Para aplicativos ASP.NET Core, confira Globalização e localização em ASP.NET Core.

  1. Defina explicitamente as propriedades CurrentUICulture e CurrentCulture em seu aplicativo. Não confie em padrões.

  2. Observe que os aplicativos ASP.NET são aplicativos gerenciados e, portanto, podem usar as mesmas classes como outros aplicativos gerenciados para recuperar, exibir e manipular informações com base na cultura.

  3. Lembre-se de que você pode especificar os seguintes três tipos de codificações no ASP.NET:

    • requestEncoding especifica a codificação recebida do navegador do cliente.
    • responseEncoding especifica a codificação a ser enviada ao navegador do cliente. Na maioria das situações, essa codificação deve ser a mesma codificação especificada para requestEncoding.
    • fileEncoding especifica a codificação padrão da análise de arquivos .aspx, .asmx e .asax.
  4. Especifique os valores dos atributos requestEncoding, responseEncoding, fileEncoding, culture e uiCulture nos seguintes três locais em um aplicativo ASP.NET:

    • Na seção de globalização de um arquivo Web.config. Este arquivo é externo no aplicativo ASP.NET. Para saber mais, confira Elemento <globalization>.
    • Em uma diretiva de página. Observe que, quando um aplicativo está em uma página, isso significa que o arquivo já foi lido. Portanto, já não é possível especificar fileEncoding e requestEncoding. Somente uiCulture, culture e responseEncoding podem ser especificados em uma diretiva de página.
    • No código do aplicativo de forma programática. Essa configuração pode variar se houver uma solicitação. Com uma diretiva de página, quando o código do aplicativo for atingido, já terá passado da hora de especificar fileEncoding e requestEncoding. Somente uiCulture, culture e responseEncoding podem ser especificados no código do aplicativo.
  5. Observe que o valor de uiCulture pode ser definido para o navegador do idioma aceito.

  6. Para aplicativos distribuídos, permita atualizações com zero tempo de inatividade (por exemplo, Aplicativos de Contêiner do Azure) ou semelhantes; você deve preparar-se para situações em que possa haver várias instâncias do aplicativo com regras de formato diferentes ou outros dados de cultura, mais relevantemente regras de fuso horário.

    • Se a implantação do aplicativo incluir um banco de dados, lembre-se de que o banco de dados terá suas próprias regras de globalização. Na maioria dos casos, você deve evitar executar quaisquer funções relacionadas à globalização no banco de dados.
    • Se a implantação do aplicativo incluir um aplicativo cliente ou front-end da Web usando recursos de globalização do cliente, suponha que os recursos do cliente diferem dos recursos disponíveis para o servidor. Considere executar exclusivamente funções de globalização no cliente.

Recomendações para testes robustos

  1. Para tornar as dependências mais explícitas e testar potencialmente mais fáceis e paralelizáveis, você deve considerar passar explicitamente configurações relevantes à cultura, como parâmetros CultureInfo, para métodos que executam formatação, e TimeZoneInfo para métodos que funcionam com datas e horas. Você também deve usar TimeProvider ou um tipo semelhante ao recuperar a hora.

  2. Para a maioria dos testes, você não deve validar explicitamente a saída exata de uma determinada operação de formatação ou o deslocamento exato de um fuso horário. A formatação e os dados de fuso horário podem ser alterados a qualquer momento e podem diferir entre duas instâncias idênticas de um sistema operacional (e processos potencialmente diferentes no mesmo computador). Depender de um valor exato torna os testes frágeis.

    • Em geral, validar que alguma saída foi recebida será suficiente (por exemplo, cadeias de caracteres não vazias ao formatar).
    • Para alguns elementos e formatos de dados, a validação de que os dados analisam o valor de entrada pode ser usada em vez disso (arredondamento). É necessário ter cuidado para os casos em que os campos são descartados (por exemplo, ano para alguns campos relacionados à data) ou o valor truncado ou arredondado (como para saída de ponto flutuante).
    • Se você tiver requisitos explícitos para validar toda a saída de formato localizado, considere criar e usar uma cultura personalizada durante a configuração do teste. Para a maioria dos casos simples, isso pode ser feito instanciando um objeto CultureInfo com o seu construtor new CultureInfo(..) e definindo as propriedades DateTimeFormat e NumberFormat. Para casos mais complicados, a subclasse do tipo permite substituir propriedades adicionais. Há possíveis benefícios adicionais para isso, como habilitar a pseudolocalização com arquivos de recursos.
    • Se você tiver requisitos explícitos para validar os resultados de todas as operações de data/hora, considere criar e usar uma instância personalizada TimeZoneInfo durante a instalação do teste. Há benefícios adicionais potenciais para isso, como habilitar testes estáveis de determinados casos de borda (por exemplo, alterações nas regras DST).

Confira também