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: