Partilhar via


ASP.NET Core Blazor globalização e localização

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.

Advertência

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 .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Importante

Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.

Para a versão atual, consulte a versão .NET 9 deste artigo.

Este artigo explica como renderizar conteúdo globalizado e localizado para usuários em diferentes culturas e idiomas.

Globalização e localização

Para a globalização, o Blazor fornece a formatação de números e datas. Para a localização , Blazor renderiza conteúdo usando o sistema de Recursos do .NET.

Um conjunto limitado de recursos de localização do ASP.NET Core é suportado:

Suportados:IStringLocalizer e IStringLocalizer<T> são suportados em aplicações Blazor.

Não suportado:IHtmlLocalizer, IViewLocalizere de localização de Anotações de Dados são ASP.NET recursos MVC principais e não suportados em aplicativos Blazor.

Este artigo descreve como usar os recursos de globalização e localização do Blazorcom base em:

  • O cabeçalho Accept-Language, que é definido pelo navegador com base nas preferências de idioma do usuário nas configurações do navegador.
  • Uma cultura definida pelo aplicativo não baseada no valor do cabeçalho Accept-Language. A configuração pode ser estática para todos os usuários ou dinâmica com base na lógica do aplicativo. Quando a configuração é baseada na preferência do usuário, a configuração geralmente é salva para recarga em visitas futuras.

Para obter informações gerais adicionais, consulte os seguintes recursos:

Muitas vezes, os termos idioma e cultura são usados indistintamente quando se lida com conceitos de globalização e localização.

Neste artigo, de idioma refere-se a seleções feitas por um usuário nas configurações do navegador. As seleções de idioma do usuário são enviadas em solicitações do navegador no cabeçalho Accept-Language. As configurações do navegador geralmente usam a palavra "idioma" na interface do usuário.

Cultura relaciona-se com os membros do .NET e da API Blazor. Por exemplo, a solicitação de um utilizador pode incluir o cabeçalho Accept-Language para especificar um idioma do ponto de vista do utilizador, mas a aplicação finalmente define a propriedade CurrentCulture ("cultura") a partir do idioma que o utilizador solicitou. API geralmente usa a palavra "cultura" em seus nomes de membros.

A orientação neste artigo não abrange a configuração do atributo de linguagem HTML da página (<html lang="...">), que as ferramentas de acessibilidade usam. Você pode definir o valor estaticamente atribuindo um idioma ao atributo lang da marca <html> ou a document.documentElement.lang em JavaScript. Você pode definir dinamicamente o valor de document.documentElement.lang com a interoperabilidade JS.

Observação

Os exemplos de código neste artigo adotam tipos de referência anuláveis (NRTs) eanálise estática de estado nulo do compilador .NET, que são suportados no ASP.NET Core em .NET 6 ou em versões superiores. Ao direcionar ASP.NET Core 5.0 ou anterior, remova a designação de tipo nulo (?) dos exemplos do artigo.

Globalização

A diretiva de atributo @bind aplica formatos e analisa valores para exibição com base no primeiro idioma preferido do utilizador que o aplicativo suporta. @bind suporta o parâmetro @bind:culture para fornecer um System.Globalization.CultureInfo para analisar e formatar um valor.

A cultura atual pode ser acessada a partir da propriedade System.Globalization.CultureInfo.CurrentCulture.

CultureInfo.InvariantCulture é usado para os seguintes tipos de campo (<input type="{TYPE}" />, onde a marca de posição {TYPE} é o tipo):

  • date
  • number

Os tipos de campo anteriores:

  • São exibidos usando suas regras de formatação apropriadas baseadas em navegador.
  • Não é possível conter texto de forma livre.
  • Forneça características de interação do usuário com base na implementação do navegador.

Blazor fornece suporte interno para renderizar valores na cultura atual. Portanto, especificar uma cultura com @bind:culture não é recomendado ao usar os tipos de campo date e number.

Os seguintes tipos de campo têm requisitos de formatação específicos e não são suportados por todos os principais navegadores, portanto, não são suportados pelo Blazor:

  • datetime-local
  • month
  • week

Para obter suporte atual do navegador para os tipos anteriores, consulte Posso usar.

Globalização .NET e suporte a componentes internacionais para Unicode (ICU) (Blazor WebAssembly)

Blazor WebAssembly utiliza uma API de globalização reduzida e um conjunto interno de Componentes Internacionais para as Localizações Unicode (ICU). Para obter mais informações, consulte Globalização do .NET e ICU: ICU no WebAssembly.

Para carregar um ficheiro de dados de ICU personalizado para controlar os locais da aplicação, veja WASM Globalization Icu. Atualmente, é necessário criar manualmente o arquivo de dados personalizado da UTI. As ferramentas do .NET para facilitar o processo de criação do arquivo estão planejadas para o .NET 10 em novembro de 2025.

Blazor WebAssembly usa uma API de globalização reduzida e um conjunto de componentes internacionais internos para localidades Unicode (ICU). Para mais informações, veja Globalização .NET e ICU: ICU em WebAssembly.

O carregamento de um subconjunto personalizado de localidades em um aplicativo Blazor WebAssembly é suportado no .NET 8 ou posterior. Para obter mais informações, acesse esta seção para uma versão 8.0 ou posterior deste artigo.

Globalização invariante

Esta seção só se aplica a cenários de Blazor do lado do cliente.

Se o aplicativo não exigir localização, configure-o para dar suporte à cultura invariante, que geralmente se baseia no inglês dos Estados Unidos (en-US). O uso da globalização invariante reduz o tamanho do download do aplicativo e resulta em uma inicialização mais rápida do aplicativo. Defina a propriedade InvariantGlobalization como true no arquivo de projeto do aplicativo (.csproj):

<PropertyGroup>
  <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>

Como alternativa, configure a globalização invariante com as seguintes abordagens:

  • Em runtimeconfig.json:

    {
      "runtimeOptions": {
        "configProperties": {
          "System.Globalization.Invariant": true
        }
      }
    }
    
  • Com uma variável de ambiente:

    • Chave: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT
    • Valor: true ou 1

Para obter mais informações, consulte Opções de configuração do Runtime para globalização (documentação do .NET).

Informações de fuso horário

Esta seção só se aplica a cenários de Blazor do lado do cliente.

A adoção de da globalização invariável leva apenas ao uso de nomes de fusos horários não localizados. Para cortar o código de fuso horário e os dados, o que reduz o tamanho do download do aplicativo e resulta em uma inicialização mais rápida do aplicativo, aplique a propriedade MSBuild <InvariantTimezone> com um valor de true no arquivo de projeto do aplicativo:

<PropertyGroup>
  <InvariantTimezone>true</InvariantTimezone>
</PropertyGroup>

Observação

<BlazorEnableTimeZoneSupport> substitui uma configuração de <InvariantTimezone> anterior. Recomendamos remover a configuração <BlazorEnableTimeZoneSupport>.

Um arquivo de dados é incluído para corrigir as informações de fuso horário. Se o aplicativo não exigir esse recurso, considere desativá-lo definindo a propriedade <BlazorEnableTimeZoneSupport> MSBuild como false no arquivo de projeto do aplicativo:

<PropertyGroup>
  <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
</PropertyGroup>

Componente de demonstração

O componente CultureExample1 seguinte pode ser usado para demonstrar conceitos de globalização e localização abordados por este artigo Blazor.

CultureExample1.razor:

@page "/culture-example-1"
@using System.Globalization

<h1>Culture Example 1</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

O formato de cadeia de caracteres numéricos (N2) no exemplo anterior (.ToString("N2")) é um especificador de formato numérico padrão do .NET . O formato N2 é suportado para todos os tipos numéricos, inclui um separador de grupo e renderiza até duas casas decimais.

Opcionalmente, adicione um item de menu à navegação no componente NavMenu (NavMenu.razor) para o componente CultureExample1.

Definir dinamicamente a cultura a partir do cabeçalho Accept-Language

Adicione o pacote Microsoft.Extensions.Localization ao aplicativo.

O cabeçalho Accept-Language é definido pelo navegador e controlado pelas preferências de idioma do utilizador nas configurações do navegador. Nas configurações do navegador, um usuário define um ou mais idiomas preferidos em ordem de preferência. A ordem de preferência é usada pelo navegador para definir valores de qualidade (q, 0-1) para cada idioma no cabeçalho. O exemplo a seguir especifica inglês dos Estados Unidos, inglês e espanhol da Costa Rica com preferência para inglês dos Estados Unidos ou inglês:

Accept-Language: en-US,en;q=0,9,es-CR;q=0,8

A cultura do aplicativo é definida pela correspondência do primeiro idioma solicitado que corresponde a uma cultura suportada do aplicativo.

Em de desenvolvimento do lado do cliente, defina a propriedade BlazorWebAssemblyLoadAllGlobalizationData como true no arquivo de projeto do aplicativo do lado do cliente (.csproj):

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Em de desenvolvimento do lado do cliente, não há suporte para definir dinamicamente a cultura a partir do cabeçalho Accept-Language.

Observação

Se a especificação do aplicativo exigir a limitação das culturas suportadas a uma lista explícita, consulte a seção Definir dinamicamente a cultura do lado do cliente por preferência do usuário deste artigo.

As aplicações são localizadas usando o Middleware de Localização . Adicione serviços de localização ao aplicativo com AddLocalization.

Adicione a seguinte linha ao arquivo Program onde os serviços são registrados:

builder.Services.AddLocalization();

Em , no desenvolvimento do lado do servidor, especifique as culturas suportadas da aplicação antes de qualquer middleware que possa verificar a cultura de solicitação. Geralmente, coloque Request Localization Middleware imediatamente antes de chamar MapRazorComponents. O exemplo a seguir configura culturas suportadas para inglês dos Estados Unidos e espanhol da Costa Rica:

No desenvolvimento do lado do servidor, , especifique as culturas suportadas da aplicação imediatamente após o Routing Middleware (UseRouting) ser adicionado ao pipeline de processamento. O exemplo a seguir configura culturas suportadas para inglês dos Estados Unidos e espanhol da Costa Rica:

app.UseRequestLocalization(new RequestLocalizationOptions()
    .AddSupportedCultures(new[] { "en-US", "es-CR" })
    .AddSupportedUICultures(new[] { "en-US", "es-CR" }));

Para obter informações sobre como integrar o middleware de localização no pipeline de middleware do ficheiro Program, consulte ASP.NET Core Middleware.

Utilize o componente CultureExample1, mostrado na secção de Demonstração do componente, para estudar como a globalização funciona. Emitir um pedido em inglês americano (en-US). Mude para o espanhol costarriquenho (es-CR) nas configurações de idioma do navegador. Solicite a página da Web novamente.

Observação

Alguns navegadores forçam você a usar a configuração de idioma padrão para solicitações e as próprias configurações da interface do usuário do navegador. Isso pode dificultar a alteração do idioma de volta para um que você entenda porque todas as telas da interface do usuário de configuração podem acabar em um idioma que você não pode ler. Um navegador como o Opera é uma boa opção para testes, pois permite definir um idioma padrão para solicitações de páginas da Web, mas deixar a interface do usuário de configurações do navegador no seu idioma.

Quando a cultura é inglês dos Estados Unidos (en-US), o componente renderizado usa formatação de data mês/dia (6/7), hora de 12 horas (AM/PM) e separadores de vírgula em números com um ponto para o valor decimal (1,999.69):

  • Data : 07/06/2021 06:45:22
  • ** Número: 1 999,69

Quando a cultura é espanhol costarriquenho (es-CR), o componente renderizado usa formatação de data dia/mês (7/6), tempo de 24 horas e separadores de período em números com uma vírgula para o valor decimal (1.999,69):

  • Data: 06/07/2021 6:49:38
  • Número: 1.999,69

Definir estaticamente a cultura do lado do cliente

Defina a propriedade BlazorWebAssemblyLoadAllGlobalizationData como true no arquivo de projeto do aplicativo (.csproj):

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

A configuração do Vinculador de Idioma Intermediário (IL) para renderização do lado do cliente remove as informações de internacionalização, exceto para localidades explicitamente solicitadas. Para obter mais informações, consulte Configurar o vinculador para ASP.NET Core Blazor.

A cultura da aplicação pode ser definida em JavaScript quando Blazor começa com a opção applicationCultureBlazor de início. O exemplo a seguir configura o aplicativo para ser iniciado usando a cultura do inglês dos Estados Unidos (en-US).

Impeça Blazor início automático adicionando autostart="false" à tag de <script> do Blazor:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Adicione o seguinte bloco de <script> após a tag <script> de Blazor e antes da tag </body> de fechamento:

Blazor Web App:

<script>
  Blazor.start({
    webAssembly: {
      applicationCulture: 'en-US'
    }
  });
</script>

Blazor WebAssemblyindependente :

<script>
  Blazor.start({
    applicationCulture: 'en-US'
  });
</script>

O valor de applicationCulture deve estar em conformidade com o formato de etiqueta de idioma BCP-47 . Para obter mais informações sobre a inicialização de Blazor, consulte ASP.NET Core Blazor inicialização.

Uma alternativa a definir a opção de início de cultura do Blazoré definir a cultura no código C#. Defina CultureInfo.DefaultThreadCurrentCulture e CultureInfo.DefaultThreadCurrentUICulture no arquivo Program para a mesma cultura.

Adicione o namespace System.Globalization ao arquivo Program:

using System.Globalization;

Adicione as configurações de cultura antes da linha que cria e executa o WebAssemblyHostBuilder (await builder.Build().RunAsync();):

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

Observação

Atualmente, as Blazor WebAssembly aplicações carregam apenas recursos com base em DefaultThreadCurrentCulture. Para obter mais informações, consulte Blazor o WASM depende apenas da cultura atual (a cultura atual da interface do usuário não é respeitada) (dotnet/aspnetcore #56824).

Use o componente mostrado na seção Demonstração do para estudar como a globalização funciona. Emitir um pedido em inglês americano (en-US). Mude para o espanhol costarriquenho (es-CR) nas configurações de idioma do navegador. Solicite a página da Web novamente. Quando o idioma solicitado é o espanhol costarriquenho, a cultura do aplicativo permanece o inglês dos Estados Unidos (en-US).

Definir estaticamente a cultura do lado do servidor

As aplicações do lado do servidor são localizadas através do uso de Middleware de Localização. Adicione serviços de localização ao aplicativo com AddLocalization.

No ficheiro Program:

builder.Services.AddLocalization();

Especifique a cultura estática no arquivo Program antes de qualquer middleware que possa verificar a cultura de solicitação. Geralmente, coloque Request Localization Middleware imediatamente antes MapRazorComponents. O exemplo a seguir configura o inglês dos Estados Unidos:

Especifique a cultura estática no arquivo Program imediatamente após o Routing Middleware (UseRouting) ser adicionado ao pipeline de processamento. O exemplo a seguir configura o inglês dos Estados Unidos:

app.UseRequestLocalization("en-US");

O valor de cultura para UseRequestLocalization deve estar em conformidade com o formato de marca de idioma BCP-47 .

Para obter informações sobre como solicitar o middleware de localização no pipeline de middleware do arquivo de Program, consulte ASP.NET Core Middleware.

As aplicações do lado do servidor são localizadas usando middleware de localização . Adicione serviços de localização ao aplicativo com AddLocalization.

Em Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

Especifique a cultura estática no Startup.Configure (Startup.cs) imediatamente após o Routing Middleware ser adicionado ao pipeline de processamento. O exemplo a seguir configura o inglês dos Estados Unidos:

app.UseRequestLocalization("en-US");

O valor de cultura para UseRequestLocalization deve estar em conformidade com o formato de marca de idioma BCP-47 .

Para obter informações sobre como integrar o middleware de localização no pipeline de middleware do Startup.Configure, consulte ASP.NET Core Middleware.

Use o componente CultureExample1 mostrado na componente de Demonstração , seção, para estudar o funcionamento da globalização. Fazer um pedido em inglês americano (en-US). Mude para o espanhol costarriquenho (es-CR) nas configurações de idioma do navegador. Solicite a página da Web novamente. Quando o idioma solicitado é o espanhol costarriquenho, a cultura do aplicativo permanece o inglês dos Estados Unidos (en-US).

Definir dinamicamente a cultura do lado do cliente por preferência do usuário

Exemplos de locais onde um aplicativo pode armazenar a preferência de um usuário incluem no armazenamento local do navegador (comum para cenários do lado do cliente), em uma localização ou banco de dados (comum para cenários do lado do servidor), ou em um serviço externo anexado a um banco de dados externo e acessado por umaAPI da web. O exemplo a seguir demonstra como usar o armazenamento local do navegador.

Adicione o pacote Microsoft.Extensions.Localization ao aplicativo.

Observação

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

Defina a propriedade BlazorWebAssemblyLoadAllGlobalizationData para true no arquivo de projeto:

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

A cultura do aplicativo para renderização do lado do cliente é definida usando a API da estrutura Blazor. A seleção de cultura de um usuário pode ser mantida no armazenamento local do navegador.

Ofereça funções JS após a tag <script> do Blazor para obter e definir a preferência cultural do utilizador utilizando o armazenamento local do navegador.

<script>
  window.blazorCulture = {
    get: () => window.localStorage['BlazorCulture'],
    set: (value) => window.localStorage['BlazorCulture'] = value
  };
</script>

Observação

O exemplo anterior polui o cliente com funções globais. Para uma melhor abordagem em aplicações de produção, consulte isolamento de JavaScript em módulos JavaScript.

Adicione os namespaces para System.Globalization e Microsoft.JSInterop à parte superior do arquivo Program:

using System.Globalization;
using Microsoft.JSInterop;

Remova a seguinte linha:

- await builder.Build().RunAsync();

Substitua a linha anterior pelo código a seguir. O código adiciona o serviço de localização do Blazorà coleção de serviços do aplicativo com AddLocalization e usa a interoperabilidade de JS para chamar JS e recuperar a seleção de cultura do usuário do armazenamento local. Se o armazenamento local não contiver uma cultura para o usuário, o código definirá um valor padrão de inglês dos Estados Unidos (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);

if (result == null)
{
    await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Observação

Atualmente, Blazor WebAssembly aplicativos carregam recursos apenas com base em DefaultThreadCurrentCulture. Para obter mais informações, consulte Blazor o WASM depende apenas da cultura atual (a cultura atual da interface do usuário não é respeitada) (dotnet/aspnetcore #56824).

O componente CultureSelector a seguir mostra como executar as seguintes ações:

  • Defina a cultura selecionada do utilizador no armazenamento local do navegador através de JS interop.
  • Recarregue o componente que eles solicitaram (forceLoad: true), que utiliza a configuração cultural atualizada.

CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

@code
{
    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
        }
    }
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

@code
{
    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
    {
        selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);

        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
        }
    }
}

Observação

Para obter mais informações sobre IJSInProcessRuntime, consulte Chamar Funções JavaScript de Métodos .NET no ASP.NET Core Blazor.

Dentro da etiqueta de fecho do elemento </main> no componente MainLayout (MainLayout.razor), adicione o componente CultureSelector:

<article class="bottom-row px-4">
    <CultureSelector />
</article>

Use o componente CultureExample1 mostrado na seção do componente Demonstração para estudar como o exemplo anterior funciona.

Definir dinamicamente a cultura do lado do servidor por preferência do usuário

Exemplos de locais onde um aplicativo pode armazenar a preferência de um usuário incluem no armazenamento local do navegador (comum para cenários do lado do cliente), em uma localização de dados cookie ou banco de dados (comum para cenários do lado do servidor), ou em um serviço externo anexado a um banco de dados externo e acessado por uma Web API . O exemplo a seguir demonstra como usar uma localização cookie.

Observação

O exemplo a seguir pressupõe que a aplicação adote uma interatividade global , especificando a renderização interativa do lado do servidor (SSR interativo) no componente Routes dentro do componente App (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Se a aplicação adotar interatividade por página ou por componente, consulte as notas no final desta seção para modificar os modos de renderização dos componentes do exemplo.

Adicione o pacote Microsoft.Extensions.Localization ao aplicativo.

Observação

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

As aplicações do lado do servidor são localizadas usando Middleware de Localização. Adicione serviços de localização ao aplicativo com AddLocalization.

No ficheiro Program:

builder.Services.AddLocalization();

Defina as culturas padrão e suportadas do aplicativo com RequestLocalizationOptions.

Antes da chamada para MapRazorComponents no pipeline de processamento de solicitação, coloque o seguinte código:

Depois que o middleware de roteamento (UseRouting) for adicionado ao pipeline de processamento de solicitação, coloque o seguinte código:

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

app.UseRequestLocalization(localizationOptions);

Para obter informações sobre como ordenar o middleware de localização na sequência de middleware, consulte ASP.NET Core Middleware.

O exemplo a seguir mostra como definir a cultura atual em um cookie que pode ser lido pelo Middleware de Localização.

Os namespaces a seguir são necessários para o componente App:

Adicione o seguinte à parte superior do arquivo de componente App (Components/App.razor):

@using System.Globalization
@using Microsoft.AspNetCore.Localization

Adicione o seguinte bloco de @code à parte inferior do arquivo de componente App:

@code {
    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    protected override void OnInitialized()
    {
        HttpContext?.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }
}

As modificações no arquivo Pages/_Host.cshtml exigem os seguintes namespaces:

Adicione o seguinte ao ficheiro:

@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

Para obter informações sobre como ordenar o middleware de localização no pipeline de middleware, consulte ASP.NET Core Middleware.

Se o aplicativo não estiver configurado para processar ações do controlador:

  • Adicione serviços MVC ao chamar AddControllers na coleção de serviços no arquivo Program.

    builder.Services.AddControllers();
    
  • Adicione o roteamento de ponto de extremidade do controlador no arquivo Program chamando MapControllers no IEndpointRouteBuilder (app):

    app.MapControllers();
    

Para fornecer uma interface do utilizador que permita a seleção de uma cultura, utilize uma abordagem baseada em redirecionamento de com a localização cookie. O aplicativo persiste a cultura selecionada do usuário por meio de um redirecionamento para um controlador. O controlador define a cultura selecionada do usuário em um cookie e redireciona o usuário de volta para o URI original. O processo é semelhante ao que acontece em um aplicativo Web quando um usuário tenta acessar um recurso seguro, onde o usuário é redirecionado para uma página de entrada e, em seguida, redirecionado de volta para o recurso original.

Controllers/CultureController.cs:

using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture, culture)));
        }

        return LocalRedirect(redirectUri);
    }
}

Advertência

Use o resultado da ação LocalRedirect, conforme mostrado no exemplo anterior, para evitar ataques de redirecionamento abertos. Para obter mais informações, consulte Impedir ataques de redirecionamento aberto no ASP.NET Core.

O componente CultureSelector a seguir mostra como chamar o método Set do CultureController com a nova cultura. O componente é colocado na pasta Shared para uso em todo o aplicativo.

CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

@code
{
    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@culture.DisplayName</option>
            }
        </select>
    </label>
</p>

@code
{
    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
    {
        selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);

        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}

Adicione o componente CultureSelector ao componente MainLayout. Coloque a seguinte marcação dentro da marca </main> de fechamento no arquivo Components/Layout/MainLayout.razor:

Adicione o componente CultureSelector ao componente MainLayout. Coloque a marcação seguinte dentro do tag de encerramento </main> no ficheiro Shared/MainLayout.razor.

<article class="bottom-row px-4">
    <CultureSelector />
</article>

Use o componente mostrado na seção componente Demonstração para estudar como o exemplo anterior funciona.

O exemplo anterior pressupõe que o aplicativo adote interatividade de global especificando o modo de renderização do Servidor Interativo no componente Routes no componente App (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Se a aplicação adotar interatividade por página/componente , faça as seguintes alterações:

  • Adicione o modo de renderização do Servidor Interativo à parte superior do arquivo do componente CultureExample1 (Components/Pages/CultureExample1.razor):

    @rendermode InteractiveServer
    
  • No layout principal do aplicativo (Components/Layout/MainLayout.razor), aplique o modo de renderização do Servidor Interativo ao componente CultureSelector:

    <CultureSelector @rendermode="InteractiveServer" />
    

Defina dinamicamente a cultura em um Blazor Web App por preferência do usuário

Esta seção se aplica aos Blazor Web Appque adotam interatividade Auto (Server e WebAssembly).

Exemplos de locais onde um aplicativo pode armazenar a preferência de um usuário incluem em de armazenamento local do navegador (comum para cenários do lado do cliente), em um cookie de localização ou banco de dados (comum para cenários do lado do servidor), armazenamento local e um cookie de localização (Blazor Web Apps com componentes de servidor e WebAssembly), ou em um serviço externo anexado a um banco de dados externo e acessado por uma API da Web . O exemplo a seguir demonstra como usar o armazenamento local do navegador para componentes renderizados do lado do cliente (CSR) e um cookie de localização para componentes renderizados do lado do servidor (SSR).

Atualizações do projeto .Client

Adicione o pacote Microsoft.Extensions.Localization ao projeto .Client.

Observação

Para obter orientação sobre como adicionar pacotes a aplicações .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

Defina a propriedade BlazorWebAssemblyLoadAllGlobalizationData para true no arquivo de projeto .Client:

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

Adicione os namespaces para System.Globalization e Microsoft.JSInterop à parte superior do arquivo de Program do projeto .Client:

using System.Globalization;
using Microsoft.JSInterop;

Remova a seguinte linha:

- await builder.Build().RunAsync();

Substitua a linha anterior pelo código a seguir. O código adiciona o serviço de localização de Blazorà coleção de serviços da aplicação com AddLocalization e utiliza a interoperabilidade de JS para chamar o JS e recuperar a seleção de idioma do utilizador a partir do armazenamento local. Se o armazenamento local não contiver uma cultura para o usuário, o código definirá um valor padrão de inglês dos Estados Unidos (en-US).

builder.Services.AddLocalization();

var host = builder.Build();

const string defaultCulture = "en-US";

var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);

if (result == null)
{
    await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Observação

Atualmente, Blazor WebAssembly aplicativos carregam recursos apenas com base em DefaultThreadCurrentCulture. Para obter mais informações, consulte Blazor o WASM depende apenas da cultura atual (a cultura atual da interface do usuário não é respeitada) (dotnet/aspnetcore #56824).

Adicione o seguinte componente CultureSelector ao projeto .Client.

O componente adota as seguintes abordagens para funcionar com os componentes SSR ou CSR:

  • O nome de exibição de cada cultura disponível na lista suspensa é fornecido por um dicionário, porque os dados de globalização do lado do cliente incluem o texto localizado dos nomes de exibição das culturas que os dados de globalização do lado do servidor fornecem. Por exemplo, a localização do lado do servidor exibe English (United States) quando en-US é a cultura e Ingles () quando uma cultura diferente é usada. Como a localização dos nomes de exibição de cultura não está disponível com a globalização Blazor WebAssembly, o nome de exibição para inglês dos Estados Unidos no cliente para qualquer cultura carregada é apenas en-US. O uso de um dicionário personalizado permite que o componente exiba pelo menos nomes completos da cultura inglesa.
  • Quando o utilizador altera a cultura, a interop JS define a cultura no armazenamento local do navegador e uma ação do controlador atualiza a localização cookie com a definição cultural. O controlador é adicionado posteriormente ao aplicativo na secção de atualizações do projeto do Servidor .

Pages/CultureSelector.razor:

@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation

<p>
    <label>
        Select your locale:
        <select @bind="@selectedCulture" @bind:after="ApplySelectedCultureAsync">
            @foreach (var culture in supportedCultures)
            {
                <option value="@culture">@cultureDict[culture.Name]</option>
            }
        </select>
    </label>
</p>

@code
{
    private Dictionary<string, string> cultureDict = 
        new()
        {
            { "en-US", "English (United States)" },
            { "es-CR", "Spanish (Costa Rica)" }
        };

    private CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-CR"),
    };

    private CultureInfo? selectedCulture;

    protected override void OnInitialized()
    {
        selectedCulture = CultureInfo.CurrentCulture;
    }

    private async Task ApplySelectedCultureAsync()
    {
        if (CultureInfo.CurrentCulture != selectedCulture)
        {
            await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);

            var uri = new Uri(Navigation.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
            var uriEscaped = Uri.EscapeDataString(uri);

            Navigation.NavigateTo(
                $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
                forceLoad: true);
        }
    }
}

No arquivo de _Imports do projeto .Client (_Imports.razor), adicione o namespace para os componentes na pasta Pages, atualizando o namespace para corresponder ao namespace do seu projeto .Client:

@using BlazorSample.Client.Pages

No projeto .Client, adicione o componente CultureSelector ao componente MainLayout. Coloque a seguinte marcação dentro da tag de encerramento </main> no arquivo Layout/MainLayout.razor.

<article class="bottom-row px-4">
    <CultureSelector @rendermode="InteractiveAuto" />
</article>

No projeto .Client, coloque o seguinte componente CultureClient para estudar como a globalização funciona para componentes de RSE.

Pages/CultureClient.razor:

@page "/culture-client"
@rendermode InteractiveWebAssembly
@using System.Globalization

<PageTitle>Culture Client</PageTitle>

<h1>Culture Client</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

No projeto .Client, coloque o seguinte componente CultureServer para estudar como a globalização funciona para componentes SSR.

Pages/CultureServer.razor:

@page "/culture-server"
@rendermode InteractiveServer
@using System.Globalization

<PageTitle>Culture Server</PageTitle>

<h1>Culture Server</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Rendered values</h2>

<ul>
    <li><b>Date</b>: @dt</li>
    <li><b>Number</b>: @number.ToString("N2")</li>
</ul>

<h2><code>&lt;input&gt;</code> elements that don't set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.CurrentCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>

<h2><code>&lt;input&gt;</code> elements that set a <code>type</code></h2>

<p>
    The following <code>&lt;input&gt;</code> elements use
    <code>CultureInfo.InvariantCulture</code>.
</p>

<ul>
    <li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
    <li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>

@code {
    private DateTime dt = DateTime.Now;
    private double number = 1999.69;
}

Use o componente mostrado na seção do componente Demonstração para estudar como a globalização funciona para um componente que herda o modo de renderização automática global. Adicione o componente CultureExample1 à pasta Pages do projeto .Client.

Adicione os componentes CultureClient, CultureServere CultureExample1 à navegação na barra lateral em Layout/NavMenu.razor:

<div class="nav-item px-3">
    <NavLink class="nav-link" href="culture-server">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Server)
    </NavLink>
</div>
<div class="nav-item px-3">
    <NavLink class="nav-link" href="culture-client">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Client)
    </NavLink>
</div>
<div class="nav-item px-3">
    <NavLink class="nav-link" href="culture-example-1">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Auto)
    </NavLink>
</div>

Atualizações do projeto do servidor

Adicione o pacote Microsoft.Extensions.Localization ao projeto de servidor.

Observação

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

As aplicações de servidor são localizadas usando Middleware de Localização. Adicione serviços de localização ao aplicativo com AddLocalization.

No arquivo de Program do projeto de servidor onde os serviços são registrados:

builder.Services.AddLocalization();

Defina as culturas padrão e suportadas do aplicativo com RequestLocalizationOptions.

Antes da chamada para MapRazorComponents no pipeline de processamento de solicitação, coloque o seguinte código:

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

app.UseRequestLocalization(localizationOptions);

O exemplo a seguir mostra como definir a cultura atual em um cookie que pode ser lido pelo Middleware de Localização.

Os namespaces a seguir são necessários para o componente App:

Adicione o seguinte à parte superior do arquivo de componente App (Components/App.razor):

@using System.Globalization
@using Microsoft.AspNetCore.Localization

A cultura do aplicativo para renderização do lado do cliente é definida usando a API da estrutura Blazor. A seleção de cultura de um usuário pode ser mantida no armazenamento local do navegador para componentes CSR.

Depois da tag <script> do Blazor, forneça funções JS para obter e definir a seleção de cultura do utilizador através do armazenamento local do navegador.

<script>
  window.blazorCulture = {
    get: () => window.localStorage['BlazorCulture'],
    set: (value) => window.localStorage['BlazorCulture'] = value
  };
</script>

Observação

O exemplo anterior polui o cliente com funções globais. Para uma abordagem melhor em aplicações de produção, consulte isolamento de JavaScript em módulos de JavaScript.

Adicione o seguinte bloco de @code à parte inferior do arquivo de componente App:

@code {
    [CascadingParameter]
    public HttpContext? HttpContext { get; set; }

    protected override void OnInitialized()
    {
        HttpContext?.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }
}

Se o projeto do servidor não estiver configurado para processar ações do controlador:

  • Adicione serviços MVC chamando AddControllers na coleção de serviços no arquivo Program:

    builder.Services.AddControllers();
    
  • Adicione o roteamento de ponto de extremidade do controlador no arquivo Program chamando MapControllers no IEndpointRouteBuilder (app):

    app.MapControllers();
    

Para permitir que um usuário selecione uma cultura para componentes SSR, use uma abordagem baseada em redirecionamento com um cookiede localização . O aplicativo persiste a cultura selecionada do usuário por meio de um redirecionamento para um controlador. O controlador define a cultura selecionada do usuário em um cookie e redireciona o usuário de volta para o URI original. O processo é semelhante ao que acontece em um aplicativo Web quando um usuário tenta acessar um recurso seguro, onde o usuário é redirecionado para uma página de entrada e, em seguida, redirecionado de volta para o recurso original.

Controllers/CultureController.cs:

using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture, culture)));
        }

        return LocalRedirect(redirectUri);
    }
}

Advertência

Use o resultado da ação LocalRedirect, conforme mostrado no exemplo anterior, para evitar ataques de redirecionamento abertos. Para obter mais informações, consulte Impedir ataques de redirecionamento aberto no ASP.NET Core.

Componentes automáticos interativos

As diretrizes nesta seção também funcionam para componentes em aplicativos que adotam a renderização por página/componente e especificam o modo de renderização automática interativa:

@rendermode InteractiveAuto

Localização

Se o aplicativo ainda não oferecer suporte à seleção de cultura dinâmica, adicione o pacote Microsoft.Extensions.Localization ao aplicativo.

Observação

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

Localização do lado do cliente

Defina a propriedade BlazorWebAssemblyLoadAllGlobalizationData como true no arquivo de projeto do aplicativo (.csproj):

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

No arquivo Program, adicione o namespace para System.Globalization no topo do arquivo.

using System.Globalization;

Adicione o serviço de localização do Blazorà coleção de serviços do aplicativo com AddLocalization:

builder.Services.AddLocalization();

Localização do lado do servidor

Use Middleware de Localização para definir a cultura da aplicação.

Se a aplicação ainda não suportar a seleção de cultura dinâmica:

  • Adicione serviços de localização ao aplicativo com AddLocalization.
  • Especifique as culturas padrão e suportadas do aplicativo no arquivo Program. O exemplo a seguir configura culturas suportadas para inglês dos Estados Unidos e espanhol da Costa Rica.
builder.Services.AddLocalization();

Coloque o middleware de localização de solicitação antes de qualquer middleware que possa verificar a cultura de solicitação. Geralmente, coloque o middleware imediatamente antes de chamar MapRazorComponents:

Imediatamente após o middleware de roteamento (UseRouting) ser adicionado ao pipeline de processamento:

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

app.UseRequestLocalization(localizationOptions);

Para obter informações sobre como ordenar o middleware de localização no pipeline de middleware, consulte ASP.NET Core Middleware.

  • Adicione serviços de localização ao aplicativo com AddLocalization.
  • Especifique as culturas padrão e suportadas do aplicativo em Startup.Configure (Startup.cs). O exemplo a seguir configura culturas suportadas para inglês dos Estados Unidos e espanhol da Costa Rica.

Em Startup.ConfigureServices (Startup.cs):

services.AddLocalization();

Em Startup.Configure imediatamente após o Routing Middleware (UseRouting) ser adicionado ao pipeline de processamento:

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

app.UseRequestLocalization(localizationOptions);

Para obter informações sobre como solicitar o middleware de localização no pipeline de middleware do Startup.Configure, consulte ASP.NET Core Middleware.

Se o aplicativo deve localizar recursos com base no armazenamento da configuração de cultura de um usuário, use uma cultura de localização cookie. O uso de um cookie garante que a conexão WebSocket possa propagar corretamente a cultura. Se os esquemas de localização forem baseados no caminho da URL ou na cadeia de caracteres de consulta, o esquema pode não ser capaz de funcionar com WebSockets, e assim não consegue manter a cultura. Portanto, a abordagem recomendada é usar uma cultura de localização cookie. Consulte a seção Definir dinamicamente a cultura do lado do servidor por preferência do usuário deste artigo para ver uma expressão de exemplo Razor que persiste a seleção de cultura do usuário.

Exemplo de recursos localizados

O exemplo de recursos localizados nesta seção funciona com os exemplos anteriores neste artigo, em que as culturas suportadas pelo aplicativo são inglês (en) como uma localidade padrão e espanhol (es) como uma localidade alternativa selecionável pelo usuário ou especificada pelo navegador.

Crie um arquivo de recurso para cada localidade. No exemplo a seguir, os recursos são criados para uma cadeia de caracteres Greeting em inglês e espanhol:

  • Inglês (en): Hello, World!
  • Espanhol (es): ¡Hola, Mundo!

Observação

O seguinte arquivo de recurso pode ser adicionado no Visual Studio clicando com o botão direito do mouse na pasta Pages e selecionando Adicionar>Novo Item>Arquivo de Recursos. Nomeie o arquivo CultureExample2.resx. Quando o editor aparecer, forneça dados para uma nova entrada. Defina o Nome do como e Valor como . Salve o arquivo.

Se estiver usando o Visual Studio Code, recomendamos instalar o ResX Viewer and Editor do Tim Heuer. Adicione um arquivo CultureExample2.resx vazio à pasta Pages. A extensão assume automaticamente o gerenciamento do arquivo na interface do usuário. Selecione o botão Adicionar Novo Recurso. Siga as instruções para adicionar uma entrada para Greeting (chave), Hello, World! (valor) e None (comentário). Salve o arquivo. Se você fechar e reabrir o arquivo, poderá ver o recurso Greeting.

ResX Viewer and Editor de Tim Heuer não pertence nem é mantido pela Microsoft e não é coberto por nenhum Contrato de Suporte ou licença da Microsoft.

O seguinte demonstra um arquivo de recurso típico. Você pode colocar manualmente arquivos de recursos na pasta Pages do aplicativo se preferir não usar ferramentas internas com um ambiente de desenvolvimento integrado (IDE), como o editor de arquivos de recursos interno do Visual Studio ou o Visual Studio Code com uma extensão para criar e editar arquivos de recursos.

Pages/CultureExample2.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Greeting" xml:space="preserve">
    <value>Hello, World!</value>
  </data>
</root>

Observação

O seguinte arquivo de recurso pode ser adicionado no Visual Studio clicando com o botão direito do mouse na pasta Pages e selecionando Adicionar>Novo Item>Arquivo de Recursos. Nomeie o arquivo CultureExample2.es.resx. Quando o editor aparecer, forneça dados para uma nova entrada. Defina o Nome para Greeting e o Valor para ¡Hola, Mundo!. Salve o arquivo.

Se estiver a usar o Visual Studio Code, recomendamos a instalação do Visualizador e Editor ResX do Tim Heuer . Adicione um arquivo CultureExample2.resx vazio à pasta Pages. A extensão assume automaticamente o gerenciamento do arquivo na interface do usuário. Selecione o botão Adicionar Novo Recurso. Siga as instruções para adicionar uma entrada para Greeting (chave), ¡Hola, Mundo! (valor) e None (comentário). Salve o arquivo. Se você fechar e reabrir o arquivo, poderá ver o recurso Greeting.

O seguinte demonstra um arquivo de recurso típico. Você pode colocar manualmente arquivos de recursos na pasta Pages do aplicativo se preferir não usar ferramentas internas com um ambiente de desenvolvimento integrado (IDE), como o editor de arquivos de recursos interno do Visual Studio ou o Visual Studio Code com uma extensão para criar e editar arquivos de recursos.

Pages/CultureExample2.es.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Greeting" xml:space="preserve">
    <value>¡Hola, Mundo!</value>
  </data>
</root>

O seguinte componente demonstra o uso da cadeia de caracteres localizada Greeting com IStringLocalizer<T>. A marcação Razor@Loc["Greeting"] no exemplo a seguir traduz a string associada ao valor Greeting, que está definido nos anteriores arquivos de recurso.

Adicione o namespace para Microsoft.Extensions.Localization ao arquivo _Imports.razor do aplicativo:

@using Microsoft.Extensions.Localization

CultureExample2.razor:

@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc

<h1>Culture Example 2</h1>

<ul>
    <li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
    <li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>

<h2>Greeting</h2>

<p>
    @Loc["Greeting"]
</p>

<p>
    @greeting
</p>

@code {
    private string? greeting;

    protected override void OnInitialized()
    {
        greeting = Loc["Greeting"];
    }
}

Opcionalmente, adicione um item de menu para o componente CultureExample2 à navegação no componente NavMenu (NavMenu.razor).

Fonte de referência do provedor de cultura WebAssembly

Para entender melhor como a estrutura processa a localização, consulte o de classe na fonte de referência ASP.NET Core.

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Mudar ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Recursos partilhados

Para criar recursos compartilhados de localização, adote a seguinte abordagem.

  • Confirme se o pacote Microsoft.Extensions.Localization é referenciado pelo projeto.

    Observação

    Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

  • Confirme se o namespace Microsoft.Extensions.Localization está disponível para os componentes Razor do projeto por meio de uma entrada no arquivo _Imports do projeto:

    @using Microsoft.Extensions.Localization
    
  • Crie uma classe fictícia com um nome de classe arbitrário. No exemplo a seguir:

    • O aplicativo usa o namespace BlazorSample e os ativos de localização usam o namespace BlazorSample.Localization.
    • A classe fictícia é chamada SharedResource.
    • O arquivo de classe é colocado em uma pasta Localization na raiz do aplicativo.

    Observação

    Não use um arquivo de designer gerado automaticamente (por exemplo, SharedResources.Designer.cs). A classe fictícia destina-se a atuar como a classe de recurso compartilhado. A presença de um arquivo de designer resulta em uma colisão de namespace.

    Localization/SharedResource.cs:

    namespace BlazorSample.Localization;
    
    public class SharedResource
    {
    }
    
  • Crie os arquivos de recursos compartilhados com um de ação de compilação de de . No exemplo a seguir:

    • Os arquivos são colocados na pasta Localization com a classe SharedResource fictícia (Localization/SharedResource.cs).

    • Nomeie os arquivos de recurso para corresponder ao nome da classe fictícia. Os arquivos de exemplo a seguir incluem um arquivo de localização padrão e um arquivo para localização em espanhol (es).

    • Localization/SharedResource.resx

    • Localization/SharedResource.es.resx

    Advertência

    Ao seguir a abordagem nesta seção, você não pode definir simultaneamente LocalizationOptions.ResourcesPath e usar IStringLocalizerFactory.Create para carregar recursos.

  • Para fazer referência à classe dummy para um IStringLocalizer<T> injetado em um componente Razor, coloque uma diretiva @using para o namespace de localização ou inclua o namespace de localização na referência de classe fictícia. Nos seguintes exemplos:

    • O primeiro exemplo indica o namespace Localization para a classe SharedResource dummy com uma diretiva @using.
    • O segundo exemplo declara explicitamente o namespace da classe SharedResource dummy.

    Em um componente Razor, use ou uma das seguintes abordagens:

    @using Localization
    @inject IStringLocalizer<SharedResource> Loc
    
    @inject IStringLocalizer<Localization.SharedResource> Loc
    

Para obter orientações adicionais, consulte Globalização e localização no ASP.NET Core.

Substituição de local usando o painel "Sensores" nas ferramentas de desenvolvimento

Ao usar a substituição da localização no painel Sensores nas ferramentas de desenvolvedor do Google Chrome ou do Microsoft Edge, o idioma de reserva é redefinido após a pré-renderização. Evite definir o idioma usando o painel Sensores durante o teste. Defina o idioma usando as configurações de idioma do navegador.

Para obter mais informações, consulte Blazor a localização não é compatível com o InteractiveServer (dotnet/aspnetcore #53707).

Recursos adicionais