Fornecer recursos localizados para idiomas e culturas em um aplicativo ASP.NET Core

Por Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya

Uma tarefa para localizar um aplicativo é fornecer cadeias de caracteres localizadas em arquivos de recurso. Este artigo é sobre como trabalhar com arquivos de recurso.

SupportedCultures e SupportedUICultures

O ASP.NET Core tem duas coleções de valores de cultura: SupportedCultures e SupportedUICultures. O objeto CultureInfo para SupportedCultures determina os resultados das funções dependentes de cultura, como data, hora, número e formatação de moeda. SupportedCultures também determina a ordem de classificação de texto, convenções de uso de maiúsculas e comparações de cadeia de caracteres. Consulte StringComparer.CurrentCulture para obter mais informações sobre como o servidor obtém a cultura. O SupportedUICultures determina quais cadeias de caracteres traduzidas (de arquivos .resx) são pesquisadas pelo ResourceManager. O ResourceManager apenas pesquisa cadeias de caracteres específicas a uma cultura determinadas por CurrentUICulture. Cada thread no .NET tem objetos CurrentCulture e CurrentUICulture. O ASP.NET Core inspeciona esses valores durante a renderização de funções dependentes de cultura. Por exemplo, se a cultura do thread atual estiver definida como "en-US" (inglês, Estados Unidos), DateTime.Now.ToLongDateString() exibirá "Thursday, February 18, 2016", mas se CurrentCulture estiver definida como "es-ES" (espanhol, Espanha), o resultado será "jueves, 18 de febrero de 2016".

Arquivos de recurso

NOTA:ResX Visualizador e Editor fornece um mecanismo alternativo para trabalhar com arquivos de recurso usando o Visual Studio Code.

Um arquivo de recurso é um mecanismo útil para separar cadeias de caracteres localizáveis do código. Cadeias de caracteres traduzidas para o idioma não padrão são arquivos de recurso .resx isolados. Por exemplo, talvez você queira criar um arquivo de recurso em espanhol chamado Welcome.es.resx contendo cadeias de caracteres traduzidas. "es" são o código de idioma para o espanhol. Para criar esse arquivo de recurso no Visual Studio:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse na pasta que conterá o arquivo de recurso e, em seguida, selecione Adicionar>Novo Item.

    Menu contextual aninhado: no Gerenciador de Soluções, um menu contextual é aberto para Recursos. Um segundo menu contextual é aberto para Adicionar mostrando o comando Novo Item realçado.

  2. Na caixa Pesquisar modelos instalados, insira "recurso" e nomeie o arquivo.

    Caixa de diálogo Adicionar Novo Item

  3. Insira o valor da chave (cadeia de caracteres nativa) na coluna Nome e a cadeia de caracteres traduzida na coluna Valor.

    Arquivo Welcome.es.resx (o arquivo de recurso Welcome em espanhol) com a palavra Hello na coluna Nome e a palavra Hola (Olá, em espanhol) na coluna valor

    O Visual Studio mostra o arquivo Welcome.es.resx.

    Gerenciador de Soluções mostrando o arquivo de recurso Welcome em espanhol (es)

Nomenclatura do arquivo de recurso

Os recursos são nomeados com o nome completo do tipo de sua classe menos o nome do assembly. Por exemplo, um recurso em francês em um projeto cujo assembly principal é LocalizationWebsite.Web.dll para a classe LocalizationWebsite.Web.Startup será nomeado Startup.fr.resx. Um recurso para a classe LocalizationWebsite.Web.Controllers.HomeController será nomeado Controllers.HomeController.fr.resx. Se o namespace da classe de destino não for o mesmo que o nome do assembly, você precisará do nome completo do tipo. Por exemplo, no projeto de exemplo, um recurso para o tipo ExtraNamespace.Tools será nomeado ExtraNamespace.Tools.fr.resx.

No projeto de exemplo, o método ConfigureServices define o ResourcesPath como "Resources", de modo que o caminho relativo do projeto para o arquivo de recurso em francês do controlador principal seja Resources/Controllers.HomeController.fr.resx. Como alternativa, você pode usar pastas para organizar arquivos de recurso. Para o controlador principal, o caminho será Resources/Controllers/HomeController.fr.resx. Se você não usar a opção ResourcesPath, o arquivo .resx entrará no diretório base do projeto. O arquivo de recurso para HomeController será nomeado Controllers.HomeController.fr.resx. A opção de usar a convenção de nomenclatura de ponto ou caminho depende de como você deseja organizar os arquivos de recurso.

Nome do recurso Nomenclatura de ponto ou caminho
Resources/Controllers.HomeController.fr.resx Ponto
Resources/Controllers/HomeController.fr.resx Caminho

Os arquivos de recurso que usam @inject IViewLocalizer em exibições do Razor seguem um padrão semelhante. O arquivo de recurso de uma exibição pode ser nomeado usando a nomenclatura de ponto ou de caminho. Os arquivos de recurso da exibição do Razor simulam o caminho de seu arquivo de exibição associado. Supondo que definimos o ResourcesPath como "Resources", o arquivo de recurso em francês associado à exibição Views/Home/About.cshtml pode ser um dos seguintes:

  • Resources/Views/Home/About.fr.resx

  • Resources/Views.Home.About.fr.resx

Se você não usar a opção ResourcesPath, o arquivo .resx de uma exibição estará localizado na mesma pasta da exibição.

RootNamespaceAttribute

O atributo RootNamespaceAttribute fornece o namespace raiz de um assembly quando o namespace raiz de um assembly é diferente do nome do assembly.

Aviso

Isso pode ocorrer quando o nome de um projeto não for um identificador .NET válido. Por exemplo, my-project-name.csproj usará o namespace raiz my_project_name e o nome do assembly my-project-name que gera esse erro.

Se o namespace raiz de um assembly é diferente do nome do assembly:

  • A localização não funciona por padrão.
  • A localização falha devido à maneira como os recursos são pesquisados dentro do assembly. RootNamespace é um valor de tempo de build que não está disponível para o processo em execução.

Se o RootNamespace é diferente de AssemblyName, inclua o seguinte no AssemblyInfo.cs (com valores de parâmetro substituídos pelos valores reais):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

O código anterior permite a resolução bem-sucedida de arquivos resx.

Comportamento de fallback da cultura

Ao procurar por um recurso, a localização participa do "fallback de cultura". Começando com a cultura solicitada, se ela não for encontrada, ela será revertida para a cultura pai dessa cultura. Além disso, a propriedade CultureInfo.Parent representa a cultura pai. Isso normalmente (mas nem sempre) significa a remoção do significante do código language-and-culture. Por exemplo, o dialeto do espanhol falado no México é "es-MX". Ele tem o pai "es", ou seja, espanhol, não específico de nenhum país.

Imagine que seu site receba uma solicitação de um recurso “Boas-vindas" usando a cultura"fr-CA". O sistema de localização procura os seguintes recursos, em ordem, e seleciona a primeira correspondência:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx (se o NeutralResourcesLanguage for "fr-CA")

Por exemplo, se você remover o designador de cultura ".fr" e tiver a cultura definida como francês, o arquivo de recurso padrão será lido e as cadeias de caracteres serão localizadas. O Gerenciador de Recursos designa um padrão ou um recurso de fallback para quando nenhuma opção atende à cultura solicitada. Se você deseja apenas retornar a chave quando um recurso está ausente para a cultura solicitada, não deve ter um arquivo de recurso padrão.

Gerar arquivos de recurso com o Visual Studio

Se você criar um arquivo de recurso no Visual Studio sem uma cultura no nome do arquivo (por exemplo, Welcome.resx), o Visual Studio criará uma classe do C# com uma propriedade para cada cadeia de caracteres. Geralmente isso não é o desejado com o ASP.NET Core. Normalmente você não tem um arquivo de recurso .resx padrão (um arquivo .resx sem o nome de cultura). Sugerimos que você crie o arquivo .resx com um nome de cultura (por exemplo Welcome.fr.resx). Quando você criar um arquivo .resx com um nome de cultura, o Visual Studio não gerará o arquivo de classe.

Adicionar outras culturas

Cada combinação de idioma e cultura (que não seja o idioma padrão) exige um arquivo de recurso exclusivo. Crie arquivos de recurso para diferentes culturas e localidades criando novos arquivos de recurso, nos quais os códigos e de idioma fazem parte do nome do arquivo (por exemplo, en-us, fr-ca e en-gb). Esses códigos são colocados entre o nome do arquivo e a extensão de arquivo .resx, como em Welcome.es-MX.resx (espanhol/México).

Próximas etapas

A localização de um aplicativo também envolve as seguintes tarefas:

Recursos adicionais

Por Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya

Uma tarefa para localizar um aplicativo é fornecer cadeias de caracteres localizadas em arquivos de recurso. Este artigo é sobre como trabalhar com arquivos de recurso.

SupportedCultures e SupportedUICultures

O ASP.NET Core tem duas coleções de valores de cultura: SupportedCultures e SupportedUICultures. O objeto CultureInfo para SupportedCultures determina os resultados das funções dependentes de cultura, como data, hora, número e formatação de moeda. SupportedCultures também determina a ordem de classificação de texto, convenções de uso de maiúsculas e comparações de cadeia de caracteres. Consulte StringComparer.CurrentCulture para obter mais informações sobre como o servidor obtém a cultura. O SupportedUICultures determina quais cadeias de caracteres traduzidas (de arquivos .resx) são pesquisadas pelo ResourceManager. O ResourceManager apenas pesquisa cadeias de caracteres específicas a uma cultura determinadas por CurrentUICulture. Cada thread no .NET tem objetos CurrentCulture e CurrentUICulture. O ASP.NET Core inspeciona esses valores durante a renderização de funções dependentes de cultura. Por exemplo, se a cultura do thread atual estiver definida como "en-US" (inglês, Estados Unidos), DateTime.Now.ToLongDateString() exibirá "Thursday, February 18, 2016", mas se CurrentCulture estiver definida como "es-ES" (espanhol, Espanha), o resultado será "jueves, 18 de febrero de 2016".

Arquivos de recurso

Um arquivo de recurso é um mecanismo útil para separar cadeias de caracteres localizáveis do código. Cadeias de caracteres traduzidas para o idioma não padrão são arquivos de recurso .resx isolados. Por exemplo, talvez você queira criar um arquivo de recurso em espanhol chamado Welcome.es.resx contendo cadeias de caracteres traduzidas. "es" são o código de idioma para o espanhol. Para criar esse arquivo de recurso no Visual Studio:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse na pasta que conterá o arquivo de recurso e, em seguida, selecione Adicionar>Novo Item.

    Menu contextual aninhado: no Gerenciador de Soluções, um menu contextual é aberto para Recursos. Um segundo menu contextual é aberto para Adicionar mostrando o comando Novo Item realçado.

  2. Na caixa Pesquisar modelos instalados, insira "recurso" e nomeie o arquivo.

    Caixa de diálogo Adicionar Novo Item

  3. Insira o valor da chave (cadeia de caracteres nativa) na coluna Nome e a cadeia de caracteres traduzida na coluna Valor.

    Arquivo Welcome.es.resx (o arquivo de recurso Welcome em espanhol) com a palavra Hello na coluna Nome e a palavra Hola (Olá, em espanhol) na coluna valor

    O Visual Studio mostra o arquivo Welcome.es.resx.

    Gerenciador de Soluções mostrando o arquivo de recurso Welcome em espanhol (es)

Nomenclatura do arquivo de recurso

Os recursos são nomeados com o nome completo do tipo de sua classe menos o nome do assembly. Por exemplo, um recurso em francês em um projeto cujo assembly principal é LocalizationWebsite.Web.dll para a classe LocalizationWebsite.Web.Startup será nomeado Startup.fr.resx. Um recurso para a classe LocalizationWebsite.Web.Controllers.HomeController será nomeado Controllers.HomeController.fr.resx. Se o namespace da classe de destino não for o mesmo que o nome do assembly, você precisará do nome completo do tipo. Por exemplo, no projeto de exemplo, um recurso para o tipo ExtraNamespace.Tools será nomeado ExtraNamespace.Tools.fr.resx.

No projeto de exemplo, o método ConfigureServices define o ResourcesPath como "Resources", de modo que o caminho relativo do projeto para o arquivo de recurso em francês do controlador principal seja Resources/Controllers.HomeController.fr.resx. Como alternativa, você pode usar pastas para organizar arquivos de recurso. Para o controlador principal, o caminho será Resources/Controllers/HomeController.fr.resx. Se você não usar a opção ResourcesPath, o arquivo .resx entrará no diretório base do projeto. O arquivo de recurso para HomeController será nomeado Controllers.HomeController.fr.resx. A opção de usar a convenção de nomenclatura de ponto ou caminho depende de como você deseja organizar os arquivos de recurso.

Nome do recurso Nomenclatura de ponto ou caminho
Resources/Controllers.HomeController.fr.resx Ponto
Resources/Controllers/HomeController.fr.resx Caminho

Os arquivos de recurso que usam @inject IViewLocalizer em exibições do Razor seguem um padrão semelhante. O arquivo de recurso de uma exibição pode ser nomeado usando a nomenclatura de ponto ou de caminho. Os arquivos de recurso da exibição do Razor simulam o caminho de seu arquivo de exibição associado. Supondo que definimos o ResourcesPath como "Resources", o arquivo de recurso em francês associado à exibição Views/Home/About.cshtml pode ser um dos seguintes:

  • Resources/Views/Home/About.fr.resx

  • Resources/Views.Home.About.fr.resx

Se você não usar a opção ResourcesPath, o arquivo .resx de uma exibição estará localizado na mesma pasta da exibição.

RootNamespaceAttribute

O atributo RootNamespaceAttribute fornece o namespace raiz de um assembly quando o namespace raiz de um assembly é diferente do nome do assembly.

Aviso

Isso pode ocorrer quando o nome de um projeto não for um identificador .NET válido. Por exemplo, my-project-name.csproj usará o namespace raiz my_project_name e o nome do assembly my-project-name que gera esse erro.

Se o namespace raiz de um assembly é diferente do nome do assembly:

  • A localização não funciona por padrão.
  • A localização falha devido à maneira como os recursos são pesquisados dentro do assembly. RootNamespace é um valor de tempo de build que não está disponível para o processo em execução.

Se o RootNamespace é diferente de AssemblyName, inclua o seguinte no AssemblyInfo.cs (com valores de parâmetro substituídos pelos valores reais):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

O código anterior permite a resolução bem-sucedida de arquivos resx.

Comportamento de fallback da cultura

Ao procurar por um recurso, a localização participa do "fallback de cultura". Começando com a cultura solicitada, se ela não for encontrada, ela será revertida para a cultura pai dessa cultura. Além disso, a propriedade CultureInfo.Parent representa a cultura pai. Isso normalmente (mas nem sempre) significa a remoção do significante do código language-and-culture. Por exemplo, o dialeto do espanhol falado no México é "es-MX". Ele tem o pai "es", ou seja, espanhol, não específico de nenhum país.

Imagine que seu site receba uma solicitação de um recurso “Boas-vindas" usando a cultura"fr-CA". O sistema de localização procura os seguintes recursos, em ordem, e seleciona a primeira correspondência:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx (se o NeutralResourcesLanguage for "fr-CA")

Por exemplo, se você remover o designador de cultura ".fr" e tiver a cultura definida como francês, o arquivo de recurso padrão será lido e as cadeias de caracteres serão localizadas. O Gerenciador de Recursos designa um padrão ou um recurso de fallback para quando nenhuma opção atende à cultura solicitada. Se você deseja apenas retornar a chave quando um recurso está ausente para a cultura solicitada, não deve ter um arquivo de recurso padrão.

Gerar arquivos de recurso com o Visual Studio

Se você criar um arquivo de recurso no Visual Studio sem uma cultura no nome do arquivo (por exemplo, Welcome.resx), o Visual Studio criará uma classe do C# com uma propriedade para cada cadeia de caracteres. Geralmente isso não é o desejado com o ASP.NET Core. Normalmente você não tem um arquivo de recurso .resx padrão (um arquivo .resx sem o nome de cultura). Sugerimos que você crie o arquivo .resx com um nome de cultura (por exemplo Welcome.fr.resx). Quando você criar um arquivo .resx com um nome de cultura, o Visual Studio não gerará o arquivo de classe.

Adicionar outras culturas

Cada combinação de idioma e cultura (que não seja o idioma padrão) exige um arquivo de recurso exclusivo. Crie arquivos de recurso para diferentes culturas e localidades criando novos arquivos de recurso, nos quais os códigos e de idioma fazem parte do nome do arquivo (por exemplo, en-us, fr-ca e en-gb). Esses códigos são colocados entre o nome do arquivo e a extensão de arquivo .resx, como em Welcome.es-MX.resx (espanhol/México).

Próximas etapas

A localização de um aplicativo também envolve as seguintes tarefas:

Recursos adicionais