.NET

10 out, 2018

ASP.NET Core: solucionando erros de conversão/formatação com Localization

278 visualizações
Publicidade

No desenvolvimento de aplicações Web são extremamente comuns tarefas como a formatação de valores financeiros e datas, bem como conversões de strings para tipos numéricos. Muitos profissionais costumam configurar seus computadores com os formatos regionais considerados ideais para os projetos que estão desenvolvendo, porém não se atentam à hipótese de uso de padrões diferentes nos computadores que hospedarão tais soluções.

A seguir temos um exemplo de site desenvolvido com o ASP.NET Core 2.1, sendo que o mesmo possibilitará a conversão de distâncias em milhas para o equivalente em Km:

Um valor de 100,5 milhas foi convertido para 161,7045 Km, seguindo o comportamento esperado para o projeto. Vale ressaltar que este print foi obtido a partir da execução local da aplicação, em uma máquina na qual foram selecionadas as configurações regionais válidas para o Brasil.

E se utilizarmos Docker com o objetivo de executar este mesmo site a partir de um container Linux?

Na próxima imagem é possível observar o resultado disto (com a execução do container na porta 1234), em que aparentemente a conversão não aconteceu da forma imaginada:

Importante recordar que nas configurações norte-americanas o caractere “.” (ponto) corresponde ao separador decimal, ao passo que “,” (vírgula) seria o separador de milhar. Assim, o valor esperado de 161,7045 Km se transformou em 1617.045 Km (além de estar com sua formatação diferente do teste inicial).

Como podemos então solucionar isto?

A resposta passa pelo suporte a Localization presente no ASP.NET Core através do middleware UseRequestLocalization. Uma chamada a esta operação no método Configure na classe Startup permitirá especificar a cultura padrão (pt-BR no caso desta aplicação de exemplo), evitando, assim, problemas de conversão/formatação:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace ConversorDistancias
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // Definindo a cultura padrão: pt-BR
            var supportedCultures = new[] { new CultureInfo("pt-BR") };
            app.UseRequestLocalization(new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture(culture: "pt-BR", uiCulture: "pt-BR"),
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            });

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

A geração de uma nova imagem após esse ajuste e a consequente criação de um container permitirão a execução de um teste em conformidade com o comportamento originalmente previsto:

Os fontes da aplicação utilizadas como base neste artigo estão disponíveis no GitHub:

Referências