Globalização e localização no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Por Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya
Um site multilíngue permite o alcance de um público mais amplo. O ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.
Consulte as diretrizes de localização do Blazor, que adicionam ou se sobrepõem às diretrizes deste artigo, em Globalização e localização do ASP.NET Core Blazor.
Termos
- Globalização (G11N): o processo de fazer com que um aplicativo dê suporte a diferentes idiomas e regiões. A abreviação vem da primeira e última letras e do número de letras entre elas.
- Localização (L10N): o processo de personalização de um aplicativo globalizado para idiomas e regiões específicos.
- Internacionalização (I18N): descreve a globalização e a localização.
- Cultura: um idioma e, opcionalmente, uma região.
- Cultura neutra: uma cultura que tem um idioma especificado, mas não uma região (por exemplo "en", "es").
- Cultura específica: uma cultura que tem um idioma e uma região especificados (por exemplo, "en-US", "en-GB", "es-CL").
- Cultura pai: a cultura neutra que contém uma cultura específica (por exemplo, "en" é a cultura pai de "en-US" e "en-GB").
- Localidade: uma localidade é o mesmo que uma cultura.
Idiomas e códigos de país/região
O formato RFC 4646 para o nome de cultura é <language code>-<country/region code>
, em que <language code>
identifica o idioma e <country/region code>
identifica a subcultura. Por exemplo, es-CL
para Espanhol (Chile), en-US
para inglês (Estados Unidos) e en-AU
para inglês (Austrália). O RFC 4646 é uma combinação de um código de cultura de duas letras minúsculas ISO 639 associado a um idioma e um código de subcultura de duas letras maiúsculas ISO 3166 associado a um país ou uma região. Para obter mais informações, consulte System.Globalization.CultureInfo.
Tarefas para localizar um aplicativo
A globalização e a localização de um aplicativo envolvem as seguintes tarefas:
- Tornar localizável o conteúdo de um aplicativo ASP.NET Core.
- Fornecer recursos localizados para as culturas e os idiomas aos quais o aplicativo dá suporte
- Implementar uma estratégia para selecionar a cultura para cada solicitação
Exibir ou baixar código de exemplo (como baixar)
Recursos adicionais
- Provedor de cultura de URL usando o middleware como filtros no ASP.NET Core
- Aplicação do RouteDataRequest CultureProvider globalmente com middlewares como filtros
IStringLocalizer
: usa o ResourceManager e ResourceReader para fornecer recursos específicos à cultura em tempo de execução. A interface tem um indexador e umIEnumerable
para retornar cadeias de caracteres localizadas.IHtmlLocalizer
: para recursos que contêm HTML.- Exibir e DataAnnotations
- Solucionar problemas de localização no ASP.NET Core
- Globalizando e localizando aplicativos do .NET
- Recursos em arquivos .resx
- Kit de Ferramentas de Aplicativo Multilíngue da Microsoft
- Localização e genéricos
Por Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya
Um site multilíngue permite o alcance de um público mais amplo. O ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.
Termos
- Globalização (G11N): o processo de fazer com que um aplicativo dê suporte a diferentes idiomas e regiões. A abreviação vem da primeira e última letras e do número de letras entre elas.
- Localização (L10N): o processo de personalização de um aplicativo globalizado para idiomas e regiões específicos.
- Internacionalização (I18N): descreve a globalização e a localização.
- Cultura: um idioma e, opcionalmente, uma região.
- Cultura neutra: uma cultura que tem um idioma especificado, mas não uma região (por exemplo "en", "es").
- Cultura específica: uma cultura que tem um idioma e uma região especificados (por exemplo, "en-US", "en-GB", "es-CL").
- Cultura pai: a cultura neutra que contém uma cultura específica (por exemplo, "en" é a cultura pai de "en-US" e "en-GB").
- Localidade: uma localidade é o mesmo que uma cultura.
Idiomas e códigos de país/região
O formato RFC 4646 para o nome de cultura é <language code>-<country/region code>
, em que <language code>
identifica o idioma e <country/region code>
identifica a subcultura. Por exemplo, es-CL
para Espanhol (Chile), en-US
para inglês (Estados Unidos) e en-AU
para inglês (Austrália). O RFC 4646 é uma combinação de um código de cultura de duas letras minúsculas ISO 639 associado a um idioma e um código de subcultura de duas letras maiúsculas ISO 3166 associado a um país ou uma região. Para obter mais informações, consulte System.Globalization.CultureInfo.
Tarefas para localizar um aplicativo
A globalização e a localização de um aplicativo envolvem as seguintes tarefas:
- Tornar localizável o conteúdo de um aplicativo ASP.NET Core.
- Fornecer recursos localizados para as culturas e os idiomas aos quais o aplicativo dá suporte
- Implementar uma estratégia para selecionar a cultura para cada solicitação
Exibir ou baixar código de exemplo (como baixar)
Recursos adicionais
- Tornar localizável o conteúdo de um aplicativo ASP.NET Core
- Fornecer recursos localizados para idiomas e culturas em um aplicativo ASP.NET Core
- Estratégias para selecionar idioma e cultura em um aplicativo ASP.NET Core localizado
- Solucionar problemas de Localização no ASP.NET Core
- Globalizando e localizando aplicativos do .NET
- O projeto Localization.StarterWeb usado no artigo.
- Recursos em arquivos .resx
- Kit de Ferramentas de Aplicativo Multilíngue da Microsoft
- Localização e genéricos
Por Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana e Hisham Bin Ateya
Um site multilíngue permite o alcance de um público mais amplo. O ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.
A internacionalização envolve System.Globalization e Localização. Globalização é o processo de criação de aplicativos que dão suporte a diferentes culturas. A globalização adiciona suporte para entrada, exibição e saída de um conjunto definido de scripts de idiomas relacionados a áreas geográficas específicas.
Localização é o processo de adaptar um aplicativo globalizado, que você já processou para possibilidade de localização, a determinada cultura/localidade. Para obter mais informações, consulte Termos de globalização e localização próximo ao final deste documento.
A localização de aplicativos envolve o seguinte:
- Tornar o conteúdo do aplicativo localizável
- Fornecer recursos localizados para as culturas e os idiomas aos quais você dá suporte
- Implementar uma estratégia para selecionar o idioma e a cultura para cada solicitação
Exibir ou baixar código de exemplo (como baixar)
Tornar o conteúdo do aplicativo localizável
IStringLocalizer e IStringLocalizer<T> foram projetados para melhorar a produtividade ao desenvolver aplicativos localizados. IStringLocalizer
usa o ResourceManager e ResourceReader para fornecer recursos específicos à cultura em tempo de execução. A interface tem um indexador e um IEnumerable
para retornar cadeias de caracteres localizadas. IStringLocalizer
não exige o armazenamento das cadeias de caracteres de idioma padrão em um arquivo de recurso. Você pode desenvolver um aplicativo direcionado à localização e não precisa criar arquivos de recurso no início do desenvolvimento. O código abaixo mostra como encapsular a cadeia de caracteres "About Title" para localização.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
}
No código anterior, a implementação IStringLocalizer<T>
é obtida da Injeção de Dependência. Se o valor localizado de "About Title" não é encontrado, a chave do indexador é retornada, ou seja, a cadeia de caracteres "About Title". Deixe as cadeias de caracteres literais de idioma padrão no aplicativo e encapsule-as no localizador, de modo que você possa se concentrar no desenvolvimento do aplicativo. Você pode desenvolve seu aplicativo com o idioma padrão e prepará-lo para a etapa de localização sem primeiro criar um arquivo de recurso padrão. Como alternativa, você pode usar a abordagem tradicional e fornecer uma chave para recuperar a cadeia de caracteres de idioma padrão. Para muitos desenvolvedores, o novo fluxo de trabalho de não ter um arquivo .resx de idioma padrão e simplesmente encapsular os literais de cadeia de caracteres pode reduzir a sobrecarga de localizar um aplicativo. Outros desenvolvedores preferirão o fluxo de trabalho tradicional, pois ele pode facilitar o trabalho com literais de cadeia de caracteres mais longas e a atualização de cadeias de caracteres localizadas.
Use a implementação IHtmlLocalizer<T>
para recursos que contêm HTML. O IHtmlLocalizer
codifica em HTML os argumentos que são formatados na cadeia de caracteres de recurso, mas não codifica em HTML a cadeia de caracteres de recurso em si. Na amostra realçada abaixo, apenas o valor do parâmetro name
é codificado em HTML.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers
{
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
Observação
No geral, apenas localize texto, não HTML.
No nível mais baixo, você pode obter IStringLocalizerFactory
com a Injeção de Dependência:
{
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
O código acima demonstra cada um dos dois métodos Create de alocador.
Você pode particionar as cadeias de caracteres localizadas por controlador, área ou ter apenas um contêiner. No aplicativo de exemplo, uma classe fictícia chamada SharedResource
é usada para recursos compartilhados.
// Dummy class to group shared resources
namespace Localization
{
public class SharedResource
{
}
}
Alguns desenvolvedores usam a classe Startup
para conter cadeias de caracteres globais ou compartilhadas. Na amostra abaixo, os localizadores InfoController
e SharedResource
são usados:
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
Localização de exibição
O serviço IViewLocalizer
fornece cadeias de caracteres localizadas para uma exibição. A classe ViewLocalizer
implementa essa interface e encontra o local do recurso no caminho do arquivo de exibição. O seguinte código mostra como usar a implementação padrão de IViewLocalizer
:
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
A implementação padrão de IViewLocalizer
encontra o arquivo de recurso com base no nome de arquivo da exibição. Não há nenhuma opção para usar um arquivo de recurso compartilhado global. ViewLocalizer
implementa o localizador usando IHtmlLocalizer
, portanto, o Razor não codifica em HTML a cadeia de caracteres localizada. Parametrize cadeias de recurso e o IViewLocalizer
codificará em HTML os parâmetros, mas não a cadeia de caracteres de recurso. Considere a seguinte marcação Razor:
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Um arquivo de recurso em francês pode conter o seguinte:
Chave | Valor |
---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
A exibição renderizada contém a marcação HTML do arquivo de recurso.
Observação
No geral, apenas localize texto, não HTML.
Para usar um arquivo de recurso compartilhado em uma exibição, injete IHtmlLocalizer<T>
:
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
Localização de DataAnnotations
As mensagens de erro de DataAnnotations são localizadas com IStringLocalizer<T>
. Usando a opção ResourcesPath = "Resources"
, as mensagens de erro em RegisterViewModel
podem ser armazenadas em um dos seguintes caminhos:
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Os atributos de não validação são localizados.
Usando uma cadeia de caracteres de recurso para várias classes
O seguinte código mostra como usar uma cadeia de caracteres de recurso para atributos de validação com várias classes:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
No código anterior, SharedResource
é a classe correspondente ao resx em que as mensagens de validação são armazenadas. Com essa abordagem, DataAnnotations usará apenas SharedResource
, em vez de o recurso para cada classe.
Fornecer recursos localizados para as culturas e os idiomas aos quais você dá suporte
SupportedCultures e SupportedUICultures
O ASP.NET Core permite que você especifique dois 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. Para obter mais informações sobre como o servidor obtém a cultura, consulte CultureInfo.CurrentCulture e CultureInfo.CurrentUICulture. O SupportedUICultures
determina quais cadeias de caracteres traduzidas (de arquivos .resx
) são pesquisadas pelo ResourceManager. O ResourceManager
pesquisa cadeias de caracteres específicas a uma cultura determinadas por CurrentUICulture
. Cada thread no .NET tem objetos CurrentCulture
e CurrentUICulture
. A estrutura inspeciona esses valores durante a renderização de funções dependentes de cultura. 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 definido como es-ES
(espanhol, Espanha), a saída 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. As cadeias de caracteres traduzidas para o idioma não padrão são isoladas nos arquivos de recurso .resx. 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:
No Gerenciador de Soluções, clique com o botão direito do mouse na pasta que contenha o arquivo de recurso >Adicionar>Novo Item.
Na caixa Pesquisar modelos instalados, insira "recurso" e nomeie o arquivo.
Insira o valor da chave (cadeia de caracteres nativa) na coluna Nome e a cadeia de caracteres traduzida na coluna Valor.
O Visual Studio mostra o arquivo Welcome.es.resx.
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 home seja Resources/Controllers.HomeController.fr.resx. Como alternativa, você pode usar pastas para organizar arquivos de recurso. Para o controlador home, 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 ISO. 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 ISO e de idioma fazem parte do nome do arquivo (por exemplo, en-us, fr-ca e en-gb). Esses códigos ISO são colocados entre o nome do arquivo e a extensão de arquivo .resx, como em Welcome.es-MX.resx (espanhol/México).
Implementar uma estratégia para selecionar o idioma e a cultura para cada solicitação
Configurar a localização
A localização é configurada no método Startup.ConfigureServices
:
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization
adiciona os serviços de localização ao contêiner de serviços. O código acima também define o caminho de recursos como "Resources".AddViewLocalization
Adiciona suporte para os arquivos de exibição localizados. Nesta amostra, a localização de exibição se baseia no sufixo do arquivo de exibição. Por exemplo, "fr" no arquivoIndex.fr.cshtml
.AddDataAnnotationsLocalization
Adiciona suporte para as mensagens de validaçãoDataAnnotations
localizadas por meio de abstraçõesIStringLocalizer
.
Middleware de localização
A cultura atual em uma solicitação é definida no Middleware de localização. O middleware de localização é habilitado no método Startup.Configure
. O middleware de localização precisa ser configurado antes de qualquer middleware que possa verificar a cultura de solicitação (por exemplo, app.UseMvcWithDefaultRoute()
). O middleware de localização deve aparecer após o Middleware de Roteamento se estiver usando RouteDataRequestCultureProvider. Para obter mais informações a ordem do middleware, veja Middleware do ASP.NET Core.
var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Se você quiser ver os comentários de código traduzidos para idiomas diferentes do inglês, informe-nos neste problema de discussão do GitHub.
UseRequestLocalization
inicializa um objeto RequestLocalizationOptions
. Em cada solicitação, a lista de RequestCultureProvider
em RequestLocalizationOptions
é enumerada e o primeiro provedor que pode determinar com êxito a cultura de solicitação é usado. Os provedores padrão são obtidos da classe RequestLocalizationOptions
:
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
A lista padrão é apresentada do mais específico ao menos específico. Mais adiante neste artigo, veremos como você pode alterar a ordem e até mesmo adicionar um provedor de cultura personalizado. Se nenhum dos provedores pode determinar a cultura de solicitação, o DefaultRequestCulture
é usado.
QueryStringRequestCultureProvider
Alguns aplicativos usarão uma cadeia de caracteres de consulta para definir a CultureInfo. Para aplicativos que usam a abordagem do cabeçalho Accept-Language ou cookie, a adição de uma cadeia de caracteres de consulta à URL é útil para depurar e testar o código. Por padrão, o QueryStringRequestCultureProvider
é registrado como o primeiro provedor de localização na lista RequestCultureProvider
. Passe os parâmetros culture
e ui-culture
da cadeia de caracteres de consulta. O seguinte exemplo define a cultura específica (idioma e região) como espanhol/México:
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
Se você passar somente uma das duas (culture
ou ui-culture
), o provedor da cadeia de caracteres de consulta definirá os dois valores usando aquela que foi passada. Por exemplo, a definição apenas da cultura definirá a Culture
e a UICulture
:
http://localhost:5000/?culture=es-MX
CookieRequestCultureProvider
Em geral, aplicativos de produção fornecerão um mecanismo para definir a cultura com cookie de cultura do ASP.NET Core. Use o método MakeCookieValue
para criar um cookie.
A CookieRequestCultureProvider
DefaultCookieName
retorna o nome padrão cookie usado para rastrear as informações de cultura preferidas do usuário. O nome padrão cookie é .AspNetCore.Culture
.
O formato do cookie é c=%LANGCODE%|uic=%LANGCODE%
, em que c
é Culture
e uic
é UICulture
, por exemplo:
c=en-UK|uic=en-US
Se você especificar apenas as informações de cultura e a cultura da interface do usuário, a cultura especificada será usada para as informações de cultura e para a cultura da interface do usuário.
O cabeçalho HTTP Accept-Language
O cabeçalho Accept-Language é configurável na maioria dos navegadores e originalmente foi criado para especificar o idioma do usuário. Essa configuração indica que o navegador foi definido para enviar ou herdou do sistema operacional subjacente. O cabeçalho HTTP Accept-Language de uma solicitação do navegador não é uma maneira infalível de detectar o idioma preferencial do usuário (consulte Definindo preferências de idioma em um navegador). Um aplicativo de produção deve incluir uma maneira para que um usuário personalize sua opção de cultura.
Definir o cabeçalho HTTP Accept-Language no IE
No ícone de engrenagem, toque em Opções da Internet.
Toque em Idiomas.
Toque em Definir Preferências de Idioma.
Toque em Adicionar um idioma.
Adicione o idioma.
Toque no idioma e, em seguida, em Mover Para Cima.
Usar um provedor personalizado
Suponha que você deseje permitir que os clientes armazenem seus idiomas e culturas nos bancos de dados. Você pode escrever um provedor para pesquisar esses valores para o usuário. O seguinte código mostra como adicionar um provedor personalizado:
private const string enUSCulture = "en-US";
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo(enUSCulture),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
// My custom request culture logic
return await Task.FromResult(new ProviderCultureResult("en"));
}));
});
Use RequestLocalizationOptions
para adicionar ou remover provedores de localização.
Alterar a ordem dos provedores de cultura de solicitação
RequestLocalizationOptions tem três provedores de cultura de solicitação padrão: QueryStringRequestCultureProvider, CookieRequestCultureProvider e AcceptLanguageHeaderRequestCultureProvider. Use a propriedade [RequestLocalizationOptions.RequestCultureProviders
]](xref:Microsoft.AspNetCore.Builder.RequestLocalizationOptions.RequestCultureProviders) para alterar a ordem desses provedores, conforme mostrado abaixo:
app.UseRequestLocalization(options =>
{
var questStringCultureProvider = options.RequestCultureProviders[0];
options.RequestCultureProviders.RemoveAt(0);
options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});
No exemplo anterior, a ordem de QueryStringRequestCultureProvider
e CookieRequestCultureProvider
é trocada, portanto, o RequestLocalizationMiddleware
procura as culturas dos cookies primeiro e, em seguida, a cadeia de caracteres de consulta.
Como mencionado anteriormente, adicione um provedor personalizado por meio do AddInitialRequestCultureProvider, que define a ordem para 0
, para esse provedor tenha precedência sobre os outros.
Definir a cultura de forma programática
Este projeto de exemplo Localization.StarterWeb no GitHub contém a interface do usuário para definir a Culture
. O arquivo Views/Shared/_SelectLanguagePartial.cshtml
permite que você selecione a cultura na lista de culturas compatíveis:
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
var cultureItems = LocOptions.Value.SupportedUICultures
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
<form id="selectLanguage" asp-controller="Home"
asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
method="post" class="form-horizontal" role="form">
<label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
onchange="this.form.submit();"
asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
</select>
</form>
</div>
O arquivo Views/Shared/_SelectLanguagePartial.cshtml
é adicionado à seção footer
do arquivo de layout para que ele fique disponível para todos os exibições:
<div class="container body-content" style="margin-top:60px">
@RenderBody()
<hr>
<footer>
<div class="row">
<div class="col-md-6">
<p>© @System.DateTime.Now.Year - Localization</p>
</div>
<div class="col-md-6 text-right">
@await Html.PartialAsync("_SelectLanguagePartial")
</div>
</div>
</footer>
</div>
O método SetLanguage
define o cookie de cultura.
[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return LocalRedirect(returnUrl);
}
Não é possível conectar o _SelectLanguagePartial.cshtml
ao código de exemplo para este projeto. O projeto Localization.StarterWeb no GitHub contém o código para o fluxo do RequestLocalizationOptions
para uma parcial do Razor por meio do contêiner de Injeção de Dependência.
Dados de rota de dados e cadeias de caracteres de consulta
Confira Comportamento de globalização de dados de rota e cadeias de caracteres de consulta de model binding.
Termos de globalização e localização
O processo de localização do aplicativo também exige uma compreensão básica dos conjuntos de caracteres relevantes geralmente usados no desenvolvimento moderno de software e uma compreensão dos problemas associados a eles. Embora todos os computadores armazenem texto como números (códigos), diferentes sistemas armazenam o mesmo texto usando números diferentes. O processo de localização se refere à tradução da interface do usuário do aplicativo para uma cultura/localidade específica.
Possibilidade de localização é um processo intermediário usado para verificar se um aplicativo globalizado está pronto para localização.
O formato RFC 4646 para o nome de cultura é <languagecode2>-<country/regioncode2>
, em que <languagecode2>
é o código de idioma e <country/regioncode2>
é o código de subcultura. Por exemplo, es-CL
para Espanhol (Chile), en-US
para inglês (Estados Unidos) e en-AU
para inglês (Austrália). O RFC 4646 é uma combinação de um código de cultura de duas letras minúsculas ISO 639 associado a um idioma e um código de subcultura de duas letras maiúsculas ISO 3166 associado a um país ou uma região. Para obter mais informações, consulte System.Globalization.CultureInfo.
Muitas vezes, internacionalização é abreviada como "I18N". A abreviação usa a primeira e última letras e o número de letras entre elas e, portanto, 18 significa o número de letras entre o primeiro "I" e o último "N". O mesmo se aplica a Globalização (G11N) e Localização (L10N).
Termos:
- Globalização (G11N): o processo de fazer com que um aplicativo dê suporte a diferentes idiomas e regiões.
- Localização (L10N): o processo de personalizar um aplicativo para determinado idioma e região.
- Internacionalização (I18N): descreve a globalização e a localização.
- Cultura: um idioma e, opcionalmente, uma região.
- Cultura neutra: uma cultura que tem um idioma especificado, mas não uma região. (por exemplo, "en", "es")
- Cultura específica: uma cultura que tem um idioma e uma região especificados. (por exemplo, "en-US", "en-GB", "es-CL")
- Cultura pai: a cultura neutra que contém uma cultura específica. (por exemplo, "en" é a cultura pai de "en-US" e "en-GB")
- Localidade: uma localidade é o mesmo que uma cultura.
Observação
Talvez você não consiga inserir vírgulas decimais em campos decimais. Para dar suporte à validação do jQuery para localidades de idiomas diferentes do inglês que usam uma vírgula (“,”) para um ponto decimal e formatos de data diferentes do inglês dos EUA, você deve tomar medidas para globalizar o aplicativo. Consulte o comentário 4076 do GitHub para obter instruções sobre como adicionar casas decimais.
Observação
Nas versões anteriores do ASP.NET Core 3.0, os aplicativos Web gravam um log do tipo LogLevel.Warning
por solicitação se a cultura solicitada não tiver suporte. Registrar um LogLevel.Warning
por solicitação pode aumentar demasiadamente os arquivos de log com informações redundantes. Esse comportamento foi alterado no ASP.NET 3.0. O RequestLocalizationMiddleware
grava um log do tipo LogLevel.Debug
, que reduz o tamanho dos logs de produção.