Práticas recomendadas para o desenvolvimento de aplicativos prontos para o mundo
Esta seção descreve as práticas recomendadas a serem seguidas ao desenvolver aplicativos prontos para o mundo.
Melhores práticas de globalização
Faça seu aplicativo Unicode internamente.
Use as classes com reconhecimento de cultura fornecidas pelo System.Globalization namespace para manipular e formatar dados.
- Para classificar, use a SortKey classe e a CompareInfo classe.
- Para comparações de cadeia de caracteres, use a CompareInfo classe.
- Para formatação de data e hora, use a DateTimeFormatInfo classe.
- Para formatação numérica, use a NumberFormatInfo classe.
- Para calendários gregorianos e não gregorianos, use a Calendar classe ou uma das implementações de calendário específicas.
Use as configurações de propriedade de cultura fornecidas pela System.Globalization.CultureInfo classe nas situações apropriadas. Use a CultureInfo.CurrentCulture propriedade para tarefas de formatação, como data e hora ou formatação numérica. Use a CultureInfo.CurrentUICulture propriedade para recuperar recursos. Observe que as
CurrentCulture
propriedades eCurrentUICulture
podem ser definidas por thread.Habilite seu aplicativo para ler e gravar dados de e para uma variedade de codificações usando as classes de codificação no System.Text namespace. Não assuma dados ASCII. Suponha que os caracteres internacionais serão fornecidos em qualquer lugar que um usuário possa inserir texto. Por exemplo, o aplicativo deve aceitar caracteres internacionais em nomes de servidor, diretórios, nomes de arquivo, nomes de usuário e URLs.
Ao usar a UTF8Encoding classe, por motivos de segurança, use o recurso de deteção de erros oferecido por essa classe. Para ativar o recurso de deteção de erros, crie uma instância da classe usando o construtor que usa um
throwOnInvalidBytes
parâmetro e defina o valor desse parâmetro comotrue
.Sempre que possível, manipule cadeias de caracteres como cadeias inteiras em vez de como uma série de caracteres individuais. Isso é especialmente importante ao classificar ou procurar substrings. Isso evitará problemas associados à análise de caracteres combinados. Você também pode trabalhar com unidades de texto em vez de caracteres únicos usando a System.Globalization.StringInfo classe.
Exiba System.Drawing texto usando as classes fornecidas pelo namespace.
Para consistência entre sistemas operacionais, não permita que as configurações do usuário substituam CultureInfoo . Use o
CultureInfo
construtor que aceita umuseUserOverride
parâmetro e defina-o comofalse
.Teste a funcionalidade do seu aplicativo em versões internacionais do sistema operacional, usando dados internacionais.
Se uma decisão de segurança for baseada no resultado de uma comparação de cadeia de caracteres ou operação de alteração de maiúsculas e minúsculas, use uma operação de cadeia de caracteres que não diferencia cultura. Essa prática garante que o resultado não seja afetado pelo valor de
CultureInfo.CurrentCulture
. Consulte a seção "Comparações de cadeia de caracteres que usam a cultura atual" de Práticas recomendadas para usar cadeias de caracteres para obter um exemplo que demonstra como comparações de cadeia de caracteres sensíveis à cultura podem produzir resultados inconsistentes.Para qualquer elemento que esteja sendo usado para intercâmbio (por exemplo, um campo em um documento JSON em uma chamada de API) ou armazenamento, use o CultureInfo; além disso, você deve especificar explicitamente um formato de ida e volta (como o especificador de
"O"
formato de"o"
data e hora). Embora as cadeias de caracteres de formato para a cultura invariante sejam estáveis e improváveis de serem alteradas, especificar uma cadeia de caracteres de formato explícito ajuda a esclarecer a intenção do seu código.- Para elementos de data/hora, considere os conselhos e observações do autor de Noda Time, Jon Skeet, que compartilha informações valiosas. Para obter mais informações, consulte Jon Skeet: Armazenar UTC não é uma bala de prata.
Os dados de globalização não são estáveis, e você deve escrever seu aplicativo e seus testes com isso em mente. É atualizado várias vezes por ano através dos canais do SO anfitrião em todas as plataformas suportadas. Esses dados normalmente não são distribuídos com o tempo de execução.
Práticas recomendadas de localização
Mova todos os recursos localizáveis para DLLs separadas 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 de objetos incorporados.
Não codifice cadeias de caracteres ou recursos da interface do usuário.
Não coloque recursos não localizáveis nas DLLs somente de recursos. Isto confunde os tradutores.
Não use cadeias de caracteres compostas que são criadas em tempo de execução a partir de frases concatenadas. As cadeias de caracteres compostas são difíceis de localizar porque geralmente assumem uma ordem gramatical em inglês que não se aplica a todos os idiomas.
Evite construções ambíguas, como "Empty Folder", onde as cadeias de caracteres podem ser traduzidas de forma diferente, dependendo das funções gramaticais dos componentes da cadeia de caracteres. Por exemplo, "vazio" pode ser um verbo ou um adjetivo, o que pode levar a diferentes traduções em línguas como o italiano ou o francês.
Evite usar imagens e ícones que contenham texto em seu aplicativo. Eles são caros para localizar.
Permita muito espaço para o comprimento das cadeias de caracteres 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.
Use a System.Resources.ResourceManager classe para recuperar recursos com base na cultura.
Use o Visual Studio para criar caixas de diálogo Windows Forms para que possam ser localizadas usando o Editor de Recursos do Windows Forms (Winres.exe). Não codifique caixas de diálogo do Windows Forms manualmente.
Providencie a localização profissional (tradução).
Para obter uma descrição completa da criação e localização de recursos, consulte Recursos em aplicativos .NET.
Práticas recomendadas de globalização para ASP.NET e outros aplicativos de servidor
Gorjeta
As práticas recomendadas a seguir são para aplicativos do ASP.NET Framework. Para aplicativos ASP.NET Core, consulte Globalização e localização no ASP.NET Core.
Defina explicitamente as CurrentUICulture propriedades e CurrentCulture em seu aplicativo. Não confie em padrões.
Observe que ASP.NET aplicativos são aplicativos gerenciados e, portanto, podem usar as mesmas classes que outros aplicativos gerenciados para recuperar, exibir e manipular informações com base na cultura.
Lembre-se de que você pode especificar os três tipos de codificações a seguir no ASP.NET:
requestEncoding
Especifica a codificação recebida do navegador do cliente.responseEncoding
Especifica a codificação a ser enviada para o navegador do cliente. Na maioria das situações, essa codificação deve ser a mesma especificada pararequestEncoding
.- fileEncoding especifica a codificação padrão para análise de arquivos .aspx, .asmx e .asax .
Especifique os valores para os
requestEncoding
atributos ,responseEncoding
,fileEncoding
,culture
, euiCulture
nos três locais a seguir em um aplicativo ASP.NET:- Na seção de globalização de um arquivo Web.config . Esse arquivo é externo ao aplicativo ASP.NET. Para obter mais informações, consulte <elemento de> globalização.
- Em uma diretiva de página. Observe que, quando um aplicativo está em uma página, o arquivo já foi lido. Portanto, é tarde demais para especificar fileEncoding e requestEncoding. Apenas
uiCulture
,culture
eresponseEncoding
pode ser especificado em uma diretiva de página. - Programaticamente no código do aplicativo. Essa configuração pode variar de acordo com a solicitação. Tal como acontece com uma diretiva de página, no momento em que o código do aplicativo é alcançado, é tarde demais para especificar
fileEncoding
erequestEncoding
. SomenteuiCulture
,culture
eresponseEncoding
pode ser especificado no código do aplicativo.
Observe que o valor uiCulture pode ser definido como o idioma de aceitação do navegador.
Para aplicativos distribuídos, permita atualizações de tempo de inatividade zero (por exemplo, Aplicativos de Contêiner do Azure) ou similares, você deve planejar situações em que pode haver várias instâncias do aplicativo com regras de formato diferentes ou outros dados de cultura, principalmente 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 frontend da Web usando recursos de globalização do cliente, suponha que os recursos do cliente sejam diferentes dos recursos disponíveis para o servidor. Considere a realização exclusiva de funções de globalização no cliente.
Recomendações para testes robustos
Para tornar as dependências mais explícitas e os testes potencialmente mais fáceis e paralelizáveis, você deve considerar a passagem explícita de configurações relevantes à cultura, como
CultureInfo
parâmetros, para métodos que executam formatação eTimeZoneInfo
para métodos que funcionam com datas e horas. Você também deve usar TimeProvider ou um tipo semelhante ao recuperar o tempo.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 mudar a qualquer momento e podem diferir entre duas instâncias idênticas de um sistema operacional (e processos potencialmente diferentes na mesma máquina). Confiar em um valor exato torna os testes frágeis.
- Geralmente, validar que alguma saída foi recebida será suficiente (por exemplo, cadeias de caracteres não vazias durante a formatação).
- Para alguns elementos e formatos de dados, a validação de que os dados são analisados para o valor de entrada pode ser usada em vez disso (roundtripping). É necessário ter cuidado com 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 vírgula flutuante).
- Se você tiver requisitos explícitos para validar todas as saídas 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
CultureInfo
objeto com seu construtornew CultureInfo(..)
e definindo asDateTimeFormat
propriedades andNumberFormat
. Para casos mais complicados, a subclassificação do tipo permite substituir propriedades adicionais. Há benefícios adicionais potenciais 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 configuração do teste. Há benefícios adicionais potenciais para isso, como permitir testes estáveis de certos casos de borda (por exemplo, alterações nas regras do horário de verão).