Executando verificação de segurança...
9

Localization em Web APIs dotnet 6/7

Motivação

Criei este documento para registrar algo não encontrei um bom material compilado para ler. Então reuni todas as informações que encontrei e organizei de forma mais lógica, para facilitar a vida de quem precisar utilizar este recurso.

Aplicação

  • Web APIs dotnet 6 e 7 (foco do material)
  • Web Applications dotnet 6 e 7

Incluindo middleware de localização

Primeiro é necessário configurar a classe Program com as informações de Localização
Importante: a posição da inclusão dos parâmetros é relevante
AddLocalization

builder.Services.AddLocalization();

SupportedCultures

var supportedCultures = new[] { "en", "pt-BR", "pt-PT", "es", "fr", "ru" };

var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture("en")
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Detalhamento

var supportedCultures = new[] { "en", "pt-BR", "pt-PT", "es", "fr", "ru" }; - A lista de idiomas que estarão disponíveis. A lista de language tags está disponivel aqui

var localizationOptions = new RequestLocalizationOptions() - Objeto sendo instânciado

.SetDefaultCulture("en") - É possivel passar o parametro de duas formas, ou como uma string, ou passando o array criado anteriormente indicando o índice da linguagem que será o padrão, por exemplo supportedCultures[0]. Este será o idioma padrão da API quando não for passado nenhum idioma

.AddSupportedCultures(supportedCultures) - indica para qual idioma o sistema deve alterar a apresentação de formatação de datas, números, moedas, etc.

.AddSupportedUICultures(supportedCultures); - Indica quais os idiomas vão ter suporte dentro da API para tradução de termos.

Arquivo de resources

Com a API configurada devemos criar os arquivos de resources, existem 3 abordagens

Nomeando por Path

Um arquivo relacionado a cada Controller ou View criado na mesma estrutura de pastas. Ex: Controllers/Calculos/Soma.en.resx

NomePorPath
Arquivos de recursos sendo criados com a mesma estrutura de pasta da Controller e da View

Resource por "dot file"

  • Um arquivo para cada Controller todos na mesma pasta, nomeados com a estrutura de pastas da controler separada por pontos. Ex: Controllers.Calculos.Soma.en.resx
NomePorDotFile
Arquivo de recursos indicando o caminho no nome do arquivo, separando nome das pastas por pontos

Um único arquivo para todas as Controllers

Criar uma pasta ou Projeto onde a classe de recursos e os recursos serão armazenados.

EstruturaDasPastas
Pasta onde a classe de recursos doi criada
ClasseDummy
Classe dummy de recursos, vazia para agregar os arquivos de recursos
CriandoResource
Nessa pasta onde foi criado a classe Resource, cria-se um arquivo de recursos
NomeandoResource
Adicionando a sigla do idioma ao nome do resource, ele automaticamente deve se aninhar a classe Resource.
RecursosCriados
Arquivos aninhados

Dentro do Resource

DentroDoResource
O arquivo de recursos tem 3 campos, Name (chave), Value (valor), Comment (comentário)

Aplicando Localization

Obs: Vou focar na explicação do uso da terceira forma de uso de recursos, um arquivo único para todas as controllers.

Dentro da controller é necessário injetar uma Interface de IStringLocalizer do tipo da classe criada anteriormente, no caso deste exemplo, Resource e inicializar o objeto no construtor.
InjetandoIStringLocalizer

	private readonly IStringLocalizer<Resource> _localizer;

	public ResoucesTesteController(IStringLocalizer<Resource> localizer)
	{
		_localizer = localizer;
	}

Para utilizar o localizer, basta chamar a instância injetada, passando a chave do resource
UsandoLocalizerChave

	[HttpGet("ResourceCadeira")]
	public string ResourceCadeira()
	{
		return _localizer["stringCadeira"];
	}

Também é possivel recuperar a lista de strings existencer no resource:
BuscandoListaDeResources

	[HttpGet("ResourceStringList")]
	public List<string> ResourceStringList()
	{
		return _localizer.GetAllStrings().ToList().Select(s => s.Value).ToList();
	}

Ou ainda uma lista de objetos do tipo LocalizedString
buscandoObjetos

	[HttpGet("ResourceList")]
	public List<LocalizedString> ResourceList()
	{
		return _localizer.GetAllStrings().ToList();
	}

Como utilizar

Ao fazer a requisição na API, adicione a querystring ?culture=fr no final do link para o endpoint utilizar o idioma indicado. Alguns exemplos de uso:

usandoFr
Utilizando o idioma Francês
usandoRu
Utilizando o idioma Russo
usandoPtBr
Utilizando o idioma pt-BR
default
Utilizando o idioma padrão do sistema

Conclusão

Meu caso de uso é tradução de mensagens de erros enviadas pela API, facilita bastante o dia a dia, pois preciso me preocupar apenas com as mensagens no meu idioma e criar chaves para estas mensagens.

Repositório

A aplicação que crie para a POC (proof of concept) está no meu github para consulta, está em docker, então para rodar na máquina provavelmente será necessário instalar o docker. Se você não usa docker, recomendo fortemente aprender nem que seja o básico, foi um divisor de águas na minha vida profissional.
https://github.com/khayo/ResourcesTeste

Fontes

  • Documentação da Microsoft (link)
  • Canal render2web (link)
  • Blog syncfusion (link)
Carregando publicação patrocinada...
1