Estes dias estive pesquisando maneiras alternativas para criar uma aplicação multi idiomas.
A primeira idéia que vem é utilizar os recursos de Culture, Global Resources e Local Resources do .NET Framewrok.
Existe muito material disponível na web sobre como utilizar os arquivos .resx para gerar texto dinâmicamente de acordo com a cultura do usuário. Para saber como utilizá-los, primeiro precisamos entender o conceito de Cultura do .NET.
Cultura nada mais é do que a combinação do idioma que é falado referente a sua localização geográfica. Isso inclui a forma de exibir as datas e valores monetários. Exemplos de cultura:
pt-BR – Português falado no Brasil
en-US – Inglês falado nos Estados Unidos
Os Global Resources e Local Resources são arquivos .resx que irão armazenar o texto a ser exibido para cada cultura. O que diferencia um do outro é a estrutura de diretórios.
Global Resources: São as informações do seu site como um todo, como por exemplo, o título da página.
Local Resources: Se referem ao conteúdo específico de uma página do site.
No ASP.NET MVC suas Views irão utilizar os recursos locais, porém, seus Controllers terão acesso apenas aos recursos globais.
Utilizando Recursos Globais
O primeiro passo é criar o diretório dos recursos globais, devemos lembrar que os recursos acessados pelas views (local resources) não estarão incluídos nesse diretório. Clique com o botão direto na raiz do seu projeto ASP.NET MVC, acesse Add ASP.NET Folder e em seguida escolha App_GlobalResources.
Dentro do diretório criado vamos adicionar um arquivo de recurso chamado Layouts.resx e preencher os textos a serem exibidos. Repare que cada texto ("Value") deve estar associado a uma chave("Name").
Agora, em nosso Controller vamos criar um método para obter o texto definido no arquivo Layouts.resx de acordo com o idioma e cultura utilizado.
Obs: Substituir "titulo" pelo parâmetro "key".
Se você prefere não ter que adicionar este método a todos os seus controles crie um classe base e faça com que seus controles herdem as propriedades desta classe. Como mostra a figura abaixo, aonde o controller de Usuarios faz referência ao controle base.
Até o momento foi criado apenas um arquivo global de recursos, que é o recurso padrão do sistema.
Agora vamos criar um novo arquivo no mesmo diretório com o nome “Layouts.en-US.resx”.
Este arquivo possui no nome uma string de cultura("en-Us"), para indicar que ele será responsável pela tradução para o inglês americano.
Utilizando Recursos Locais
Os textos gerados pelos controllers já estão sendo traduzidos, mas para as Views, os arquivos de recursos globais não podem ser utilizados.
Para implementar a tradução em uma View , precisamos usar os Recursos Locais.
Clique com o botão direto no diretório da View, selecione Add ASP.NET Folder e em seguida escolha App_LocalResources.
Atenção, você deve criar um arquivo de recurso com o mesmo nome da View que irá utilizá-lo(no exemplo temos o arquivo Index.chtml no grupo de views, o arquivo de resource deve se cahamar Index.resx). Adicione a string de cultura para obter outras linguagens, assim como foi feito com os recursos globais.
A figura abaixo demonstra um exemplo:
Para recuperar o texto do arquivo de resources dentro da nossa view de uma maneira limpa, vamos criar uma classe Extension.cs e referênciá-la no web.config do nosso projeto, para que todas as páginas sejam capazes de interpretar a chamada do método LocalResources (responsável por retornar o texto na cultura correta). Segue abaixo a figura com um exemplo:
Agora para recuperar o texto dentro da view basta adicionar o código @this.LocalResources("chave") como mostra a imagem abaixo.
Um dos maiores problemas desse tipo de abordagem é o reaproveitamento dos arquivos .resx.
Caso haja outra camada de apresentação, será necessário criar novos recursos globais e locais. As própias views não conseguem compartilhar recursos entre si, gerando uma infinidade de arquivos .resx para cada controller.
Pensando nisso, criei uma nova camada no projeto, que será responsável por traduzir os textos de uma maneira diferente.
A intenção dessa nova bordagem é ter um único arquivo .xml que conterá todos os textos a serem exibidos no site, centralizando os textos para serem utilizados por N-camadas do sistema.
A classe Controller.cs fica responsável por carregar na cache a tabela de textos de acordo com o idioma selecionado para o usuário. Temos também a classe HttpCache responsável por encapsular o acesso aos objetos da cache e as operações de leitura e gravação. A estrutura do projeto e do arquivo XML que armazena as linguagens estão na imagem abaixo:
Temos também o mpetodo responsável por carregar a tabela com base no arquivo xml, de acordo com a cultura solicitada.
Tendo criada nossa nova camada de tradução. Agora basta adiciona-la como referência no nosso projeto MVC para podermos utilizar tanto nos Controllers, Models e Views. Podemos também adicionar a referência em outras camadas.
Para usarmos em um controller ou model precisamos apenas adicionar o código: Traducao.Controller.Texto(id);
Para usarmos nas Views em razor, adicionamos o código: @Traducao.Controller.Texto(id)
O exemplo acima demonstra uma situação aonde é possível alterar o idioma da aplicação inteira em tempo de execução, através do arquivo web.config. O exemplo pode ser facilmente modificado para modificar o idioma de acordo com as preferências do usuário.
O maior problema nesta abordagem aparece quando pensamos nas Data Anottations dos nossos modelos.
As validações geradas automaticamente pelos modelos são compiladas e não podem ser dinâmicas.
Por exemplo:
namespace IntcomProjectManager.Models.Facades
{
public class Usuarios: DataAccessLayer.Usuarios
{
[Required(ErrorMessage = "*")] //Não pode ser dinâmica referenciando Traducao.Controller.Texto
public string Nome { get; set; }
[Required(ErrorMessage = "*")]
public string Email { get; set; }
[Required(ErrorMessage = "*")]
public string Cpf { get; set; }
[Required(ErrorMessage = "*")]
public string Senha { get; set; }
}
Para acabar com este problema andei pesquisando na internet e achei um excelente post do Jonas Gauffin (http://blog.gauffin.org/2011/09/easy-model-and-validation-localization-in-asp-net-mvc3/) ele disponibilizou uma interface para ser implementada que permite que usemos arquivos XML, bancos de dados ou arquivos de resources para gerar Data Annotations com localização de uma maneira limpa e eficiente.










Muito bom post
ReplyDeletePara projetos de localização usando arquivos .resx ou .xml, eu recomendo esta plataforma de tradução do softwares - https://poeditor.com/
ReplyDeleteMuito Bom parabéns
ReplyDelete