Partilhar via


Globalização e localização no ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

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

Um sítio Web multilingue permite que um sítio Web chegue a um público mais vasto. ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.

Para Blazor obter orientações de localização, que adicionam ou substituem as diretrizes deste artigo, consulte ASP.NET Globalização e localização principaisBlazor.

Terms

  • Globalização (G11N): O processo de fazer com que um aplicativo suporte diferentes idiomas e regiões. A abreviatura vem da primeira e da última letra 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): Globalização e localização.
  • Cultura: uma língua e, opcionalmente, uma região.
  • Cultura neutra: uma cultura que tem uma língua específica, mas não uma região (por exemplo, "en", "es").
  • Cultura específica: uma cultura que tem uma língua e uma região específicas (por exemplo, "en-US", "en-GB", "es-CL").
  • Cultura parental: A cultura neutra que contém uma cultura específica (por exemplo, "en" é a cultura mãe de "en-US" e "en-GB").
  • Localidade: uma localidade é o mesmo que uma cultura.

Códigos de idioma e país/região

O formato RFC 4646 para o nome da cultura é <language code>-<country/region code>, onde <language code> identifica o idioma e <country/region code> identifica a subcultura. Por exemplo, es-CL para espanhol (Chile), en-US inglês (Estados Unidos) e en-AU inglês (Austrália). RFC 4646 é uma combinação de um código de cultura minúscula de duas letras ISO 639 associado a um idioma e um código de subcultura maiúscula de duas letras ISO 3166 associado a um país ou região. Para obter mais informações, consulte System.Globalization.CultureInfo.

Tarefas para localizar um aplicativo

Globalizar e localizar um aplicativo envolve as seguintes tarefas:

Visualizar ou descarregar amostra de código (como descarregar)

Recursos adicionais

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

Um sítio Web multilingue permite que um sítio Web chegue a um público mais vasto. ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.

Terms

  • Globalização (G11N): O processo de fazer com que um aplicativo suporte diferentes idiomas e regiões. A abreviatura vem da primeira e da última letra 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): Globalização e localização.
  • Cultura: uma língua e, opcionalmente, uma região.
  • Cultura neutra: uma cultura que tem uma língua específica, mas não uma região (por exemplo, "en", "es").
  • Cultura específica: uma cultura que tem uma língua e uma região específicas (por exemplo, "en-US", "en-GB", "es-CL").
  • Cultura parental: A cultura neutra que contém uma cultura específica (por exemplo, "en" é a cultura mãe de "en-US" e "en-GB").
  • Localidade: uma localidade é o mesmo que uma cultura.

Códigos de idioma e país/região

O formato RFC 4646 para o nome da cultura é <language code>-<country/region code>, onde <language code> identifica o idioma e <country/region code> identifica a subcultura. Por exemplo, es-CL para espanhol (Chile), en-US inglês (Estados Unidos) e en-AU inglês (Austrália). RFC 4646 é uma combinação de um código de cultura minúscula de duas letras ISO 639 associado a um idioma e um código de subcultura maiúscula de duas letras ISO 3166 associado a um país ou região. Para obter mais informações, consulte System.Globalization.CultureInfo.

Tarefas para localizar um aplicativo

Globalizar e localizar um aplicativo envolve as seguintes tarefas:

Visualizar ou descarregar amostra de código (como descarregar)

Recursos adicionais

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

Um sítio Web multilingue permite que o sítio chegue a um público mais vasto. ASP.NET Core fornece serviços e middleware para localização em diferentes idiomas e culturas.

Internacionalização envolve System.Globalization e Localização. A globalização é o processo de criação de aplicativos que suportam diferentes culturas. A globalização adiciona suporte para entrada, exibição e saída de um conjunto definido de scripts de linguagem relacionados a áreas geográficas específicas.

Localização é o processo de adaptação de um aplicativo globalizado, que você já processou para localização, a uma cultura/localidade específica. Para obter mais informações, consulte Termos de globalização e localização no final deste documento.

A localização de aplicativos envolve o seguinte:

  1. Tornar o conteúdo do aplicativo localizável
  2. Fornecer recursos localizados para os idiomas e culturas aos quais você oferece suporte
  3. Implementar uma estratégia para selecionar o idioma/cultura para cada solicitação

Visualizar ou descarregar amostra de código (como descarregar)

Tornar o conteúdo do aplicativo localizável

IStringLocalizer e IStringLocalizer<T> foram arquitetados para melhorar a produtividade ao desenvolver aplicativos localizados. IStringLocalizer usa o ResourceManager e o ResourceReader para fornecer recursos da cultura específicos em tempo de execução. A interface tem um indexador e um IEnumerable para retornar cadeias de caracteres localizadas. IStringLocalizer não requer o armazenamento das cadeias de caracteres de idioma padrão em um arquivo de recurso. Você pode desenvolver um aplicativo direcionado para localização e não precisa criar arquivos de recursos no início do desenvolvimento. O código abaixo mostra como encapsular a cadeia de caracteres "Sobre o título" 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 IStringLocalizer<T> implementação vem de Injeção de dependência. Se o valor localizado de "About Title" não for encontrado, a chave do indexador será retornada, ou seja, a string "About Title". Você pode deixar as cadeias de caracteres literais de idioma padrão no aplicativo e envolvê-las no localizador, para que você possa se concentrar no desenvolvimento do aplicativo. Você desenvolve seu aplicativo com seu idioma padrão e o prepara 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 longos e facilitar a atualização de cadeias de caracteres localizadas.

Use a IHtmlLocalizer<T> implementação para recursos que contêm HTML. IHtmlLocalizer HTML codifica argumentos que são formatados na cadeia de caracteres de recurso, mas não codifica HTML a cadeia de caracteres de recurso em si. No exemplo destacado abaixo, apenas o valor do parâmetro é codificado name 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();
        }

Note

Geralmente, localize apenas texto, não HTML.

No nível mais baixo, você pode sair IStringLocalizerFactory da 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 de criação da fábrica.

Você pode particionar suas 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 Startup classe para conter cadeias de caracteres globais ou compartilhadas. No exemplo abaixo, o InfoController e os SharedResource localizadores 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;
    }

Ver localização

O IViewLocalizer serviço fornece cadeias de caracteres localizadas para uma vista. A ViewLocalizer classe implementa essa interface e localiza o local do recurso a partir do caminho do arquivo de exibição. O código a seguir 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 ficheiro de recursos com base no nome do ficheiro da vista. Não há opção para usar um arquivo de recurso compartilhado global. ViewLocalizer implementa o localizador usando IHtmlLocalizer, portanto Razor não codifica em HTML a cadeia de caracteres localizada. Você pode parametrizar cadeias de caracteres de recursos e IViewLocalizer codificará HTML os parâmetros, mas não a cadeia de caracteres de recurso. Considere a seguinte Razor marcação:

@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]

Um arquivo de recurso francês pode conter o seguinte:

Key Value
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

A exibição renderizada conteria a marcação HTML do arquivo de recurso.

Note

Geralmente, localize apenas texto, não HTML.

Para usar um arquivo de recurso compartilhado em um modo de 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 DataAnnotations são localizadas através de IStringLocalizer<T>. Usando a opção ResourcesPath = "Resources", as mensagens de erro em RegisterViewModel podem ser armazenadas em qualquer 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 não relacionados à validação são localizados.

Usando uma cadeia de caracteres de recurso para várias classes

O código a seguir 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 onde suas mensagens de validação são armazenadas. Com essa abordagem, DataAnnotations usará SharedResourceapenas , em vez do recurso para cada classe.

Fornecer recursos localizados para os idiomas e culturas aos quais você oferece suporte

SupportedCultures e SupportedUICultures

ASP.NET Core permite especificar dois valores de cultura, SupportedCultures e SupportedUICultures. O CultureInfo objeto for SupportedCultures determina os resultados de funções dependentes da cultura, como formatação de data, hora, número e moeda. SupportedCultures também determina a ordem de ordenação do texto, convenções de capitalização e comparações de strings. 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 ficheiros .resx) são pesquisadas pelo ResourceManager. O ResourceManager procura cadeias de caracteres específicas da cultura que são determinadas pelo CurrentUICulture. Cada thread no .NET tem CurrentCulture e CurrentUICulture objetos. A estrutura inspeciona esses valores ao renderizar funções dependentes da 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 definida como es-ES (espanhol, Espanha), a saída será jueves, 18 de febrero de 2016.

Arquivos de recursos

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 em arquivos de recursos .resx . Por exemplo, talvez você queira criar um arquivo de recurso espanhol chamado Welcome.es.resx contendo cadeias de caracteres traduzidas. "es" é o código da língua espanhola. Para criar este 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 Adicionar>Novo Item.

    Menu contextual aninhado: no Explorador de Soluções, um menu contextual para Recursos está aberto. Um segundo menu contextual para Adicionar está aberto, mostrando o comando Novo Item destacado.

  2. Na caixa Pesquisar modelos instalados , digite "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 de boas-vindas para espanhol) com a palavra Hello na coluna Nome e a palavra Hola (Hello em espanhol) na coluna Valor

    Visual Studio mostra o arquivo Welcome.es.resx .

    Solution Explorer mostrando o arquivo de recurso Welcome Spanish (es)

Nomeação de ficheiros de recursos

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

No projeto de exemplo, o método ConfigureServices define ResourcesPath como "Resources", portanto, o caminho relativo do projeto para o arquivo de recurso francês do controlador Home é Resources/Controllers.HomeController.fr.resx. Como alternativa, você pode usar pastas para organizar arquivos de recursos. Para o controlador doméstico, o caminho seria Resources/Controllers/HomeController.fr.resx. Se você não usar a ResourcesPath opção, o arquivo .resx irá para o diretório base do projeto. O arquivo de recurso para HomeController seria chamado Controllers.HomeController.fr.resx. A escolha de usar a convenção de nomenclatura por ponto ou por caminho depende de como pretendes organizar os teus ficheiros de recursos.

Nome do recurso Nomeação de ponto ou caminho
Resources/Controllers.HomeController.fr.resx Dot
Resources/Controllers/HomeController.fr.resx Path

Os ficheiros de recursos que usam @inject IViewLocalizer nas Razor vistas seguem um padrão semelhante. O ficheiro de recursos para uma visualização pode ser nomeado através de nomes de ponto ou de caminho. Razor Os arquivos de recursos de exibição imitam o caminho do arquivo de exibição associado. Supondo que definimos o ResourcesPath como "Recursos", o arquivo de recurso francês associado à Views/Home/About.cshtml exibição pode ser um dos seguintes:

  • Recursos/Visualizações/Home/About.fr.resx

  • Recursos/Visualizações.Home. Sobre.fr.resx

Se não usar a ResourcesPath opção, o ficheiro .resx para uma vista estará localizado na mesma pasta que a vista.

RootNamespaceAttribute

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

Warning

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

Se o namespace raiz de uma assemblagem for diferente do nome da assemblagem:

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

Se o RootNamespace for diferente do AssemblyName, inclua o seguinte em AssemblyInfo.cs (com valores de parâmetros 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 contingência da cultura

Ao procurar um recurso, a localização envolve-se em "retorno cultural". A partir da cultura solicitada, se não for encontrada, ela reverte para a cultura mãe dessa cultura. Diga-se de passagem, a propriedade CultureInfo.Parent representa a cultura de origem. Isso geralmente (mas nem sempre) significa remover o identificador nacional do código ISO. Por exemplo, o dialeto do espanhol falado no México é "es-MX". Possui origem "es" - espanhol não específico a qualquer país.

Imagine que o seu site recebe um pedido de um recurso "Bem-vindo", no âmbito da 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 recurso padrão ou de fallback para quando nada atende à cultura solicitada. Se você quiser apenas retornar a chave quando faltar um recurso para a cultura solicitada, você não deve ter um arquivo de recurso padrão.

Gerar arquivos de recursos 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 C# com uma propriedade para cada cadeia de caracteres. Isso geralmente não é o que você quer com ASP.NET Core. Normalmente, você não tem um arquivo de recurso .resx padrão (um arquivo .resx sem o nome da cultura). Sugerimos que você crie o arquivo .resx com um nome de cultura (por exemplo , Welcome.fr.resx). Quando você cria um arquivo .resx com um nome de cultura, o Visual Studio não gera o arquivo de classe.

Adicionar outras culturas

Cada combinação de idioma e cultura (diferente do idioma padrão) requer um arquivo de recurso exclusivo. Você cria arquivos de recursos para diferentes culturas e localidades criando novos arquivos de recursos nos quais os códigos de idioma ISO fazem parte do nome do arquivo (por exemplo, en-us, fr-cae en-gb). Esses códigos ISO são colocados entre o nome do arquivo e a extensão de arquivo .resx , como em Bem-vindo.es-MX.resx (Espanhol/México).

Implementar uma estratégia para selecionar o idioma/cultura para cada solicitação

Configurar localização

A localização é configurada no Startup.ConfigureServices método:

services.AddLocalization(options => options.ResourcesPath = "Resources");

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization Adiciona os serviços de localização ao contêiner Serviços. O código acima também define o caminho de recursos como "Recursos".

  • AddViewLocalization Adiciona suporte para arquivos de exibição localizados. Neste exemplo de exibição, a localização é baseada no sufixo do arquivo de exibição. Por exemplo, "fr" no Index.fr.cshtml arquivo.

  • AddDataAnnotationsLocalization adiciona suporte a mensagens de validação localizadas DataAnnotations por meio de IStringLocalizer abstrações.

Middleware de localização

A cultura atual em uma solicitação é definida no Middleware de localização. O middleware de localização é ativado no método Startup.Configure. O middleware de localização deve 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 encaminhamento se estiver usando RouteDataRequestCultureProvider. Para obter mais informações sobre a ordem do middleware, consulte ASP.NET Core Middleware.

var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Se quiser ver os comentários de código traduzidos para outros idiomas além do inglês, avise-nos nesta discussão do GitHub .

UseRequestLocalization Inicializa um RequestLocalizationOptions objeto. Em cada solicitação, a lista de RequestCultureProvider no RequestLocalizationOptions é enumerada e o primeiro provedor que consiga determinar com êxito a cultura da solicitação é usado. Os provedores padrão vêm da RequestLocalizationOptions classe:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

A lista padrão vai do mais específico ao menos específico. Mais adiante no artigo, veremos como você pode alterar a ordem e até mesmo adicionar um provedor de cultura personalizado. Se nenhum dos provedores puder determinar a cultura de solicitação, o DefaultRequestCulture será usado.

QueryStringRequestCultureProvider

Alguns aplicativos usarão uma cadeia de caracteres de consulta para definir o CultureInfo. Para aplicativos que usam a cookie abordagem de cabeçalho ou Accept-Language, adicionar uma cadeia de caracteres de consulta à URL é útil para depurar e testar código. Por padrão, o QueryStringRequestCultureProvider é registrado como o primeiro provedor de localização na RequestCultureProvider lista. Você passa os parâmetros culture da cadeia de caracteres de consulta e ui-culture. O exemplo a seguir 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 apenas um dos dois (culture ou ui-culture), o provedor de cadeia de caracteres de consulta definirá ambos os valores usando o que você passou. Por exemplo, definir apenas a cultura definirá o Culture e o UICulture:

http://localhost:5000/?culture=es-MX

CookieRequestCultureProvider

Os aplicativos de produção geralmente fornecem um mecanismo para definir a cultura com a cultura ASP.NET Core cookie. Use o MakeCookieValue método para criar um cookie.

O CookieRequestCultureProviderDefaultCookieName retorna o nome padrão cookie usado para rastrear as informações de cultura preferidas do usuário. O nome cookie padrão é .AspNetCore.Culture.

O cookie formato é c=%LANGCODE%|uic=%LANGCODE%, onde c é Culture e uic é UICulture, por exemplo:

c=en-UK|uic=en-US

Se você especificar apenas uma das informações de cultura e a cultura da interface do usuário, a cultura especificada será usada para as informações de cultura e a cultura da interface do usuário.

O cabeçalho HTTP Accept-Language

O cabeçalhoAccept-Language é configurável na maioria dos navegadores e foi originalmente destinado a especificar o idioma do usuário. Essa configuração indica o que o navegador foi configurado 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 detetar o idioma preferido do usuário (consulte Definindo preferências de idioma em um navegador). Um aplicativo de produção deve incluir uma maneira de um usuário personalizar sua escolha de cultura.

Definir o cabeçalho HTTP Accept-Language no IE

  1. No ícone de engrenagem, toque em Opções da Internet.

  2. Toque em Idiomas.

    Opções da Internet

  3. Toque em Definir preferências de idioma.

  4. Toque em Adicionar um idioma.

  5. Adicione o idioma.

  6. Toque no idioma e, em seguida, toque em Mover para cima.

Usar um provedor personalizado

Suponha que você queira permitir que seus clientes armazenem seu idioma e cultura em seus bancos de dados. Você pode escrever um provedor para procurar esses valores para o usuário. O código a seguir 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, CookieRequestCultureProvidere 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, então o RequestLocalizationMiddleware procura as culturas nos cookies primeiro, depois na cadeia de consulta.

Como mencionado anteriormente, adicione um fornecedor personalizado através de AddInitialRequestCultureProvider, que define a ordem para 0, garantindo que este fornecedor tenha precedência sobre os outros.

Defina a cultura programaticamente

Este exemplo de projeto Localization.StarterWeb no GitHub contém a interface do usuário para definir o Culture. O Views/Shared/_SelectLanguagePartial.cshtml arquivo permite que você selecione a cultura da lista de culturas suportadas:

@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 Views/Shared/_SelectLanguagePartial.cshtml arquivo é adicionado à footer seção do arquivo de layout para que esteja disponível para todas as visualizações:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

O SetLanguage método define a cultura cookie.

[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 ligar o _SelectLanguagePartial.cshtml no código de exemplo para este projeto. O projeto Localization.StarterWeb no GitHub tem código para transferir RequestLocalizationOptions para um Razor parcial através do contentor de Injeção de Dependências.

Dados de rota de vinculação de modelo e cadeias de caracteres de consulta

Consulte Comportamento de globalização de dados de rota de vinculação de modelo e cadeias de caracteres de consulta.

Termos de globalização e localização

O processo de localização do seu aplicativo também requer uma compreensão básica dos conjuntos de caracteres relevantes comumente usados no desenvolvimento de software moderno e uma compreensão dos problemas associados a eles. Embora todos os computadores armazenem texto como números (códigos), sistemas diferentes armazenam o mesmo texto usando números diferentes. O processo de localização refere-se à tradução da interface do usuário (UI) do aplicativo para uma cultura/localidade específica.

A localizabilidade é um processo intermediário para verificar se um aplicativo globalizado está pronto para localização.

O formato RFC 4646 para o nome da cultura é <languagecode2>-<country/regioncode2>, onde <languagecode2> é o código do idioma e <country/regioncode2> é o código da subcultura. Por exemplo, es-CL para espanhol (Chile), en-US inglês (Estados Unidos) e en-AU inglês (Austrália). RFC 4646 é uma combinação de um código de cultura minúscula de duas letras ISO 639 associado a um idioma e um código de subcultura maiúscula de duas letras ISO 3166 associado a um país ou região. Para obter mais informações, consulte System.Globalization.CultureInfo.

A internacionalização é muitas vezes abreviada na forma de "I18N". A abreviatura leva a primeira e a última letras e o número de letras entre elas, então 18 significa o número de letras entre o primeiro "I" e o último "N". O mesmo se aplica à Globalização (G11N) e à Localização (L10N).

Terms:

  • Globalização (G11N): O processo de fazer com que um aplicativo suporte diferentes idiomas e regiões.
  • Localização (L10N): O processo de personalização de um aplicativo para um determinado idioma e região.
  • Internacionalização (I18N): Descreve tanto a globalização como a localização.
  • Cultura: É uma língua e, opcionalmente, uma região.
  • Cultura neutra: uma cultura que tem uma língua específica, mas não uma região. (por exemplo, "en", "es")
  • Cultura específica: uma cultura que tem um idioma e uma região específicos. (por exemplo, "en-US", "en-GB", "es-CL")
  • Cultura parental: A cultura neutra que contém uma cultura específica. (por exemplo, "en" é a cultura mãe de "en-US" e "en-GB")
  • Localidade: uma localidade é o mesmo que uma cultura.

Note

Talvez não seja possível inserir vírgulas decimais em campos decimais. Para dar suporte à validação do jQuery para localidades diferentes do inglês que usam uma vírgula (",") para um ponto decimal e formatos de data não US-English, você deve tomar medidas para globalizar seu aplicativo. Consulte este comentário 4076 do GitHub para obter instruções sobre como adicionar vírgula decimal.

Note

Antes de ASP.NET aplicativos Web Core 3.0, escreva um log do tipo LogLevel.Warning por solicitação se a cultura solicitada não for suportada. Registrar um LogLevel.Warning por solicitação pode criar grandes arquivos de log com informações redundantes. Esse comportamento foi alterado no ASP.NET Core 3.0. O RequestLocalizationMiddleware grava um log do tipo LogLevel.Debug, o que reduz o tamanho dos logs de produção.

Recursos adicionais