Há momentos em que precisamos parametrizar as ações de controllers com outros tipos de dados que vão além de inteiros e strings, e sem ainda falar de tipos de complexos, o tipo DateTime pode ser uma necessidade muito comum em alguns casos. O problema é que este tipo de dado possui diversas formatações e sua validade varia de acordo com a cultura contra qual ele está sendo validado.
Sendo assim, podemos nos deparar com alguns problemas, onde apesar de ser uma data válida se considerarmos o formato brasileiro, ela pode ser considerada inválida pela API que utiliza o formato americano para tratar e vice versa. Mesmo que a cultura da aplicação esteja definida para a região correta, os componentes internos do ASP.NET Web API não são capazes de entender o formato da data que o cliente deve passar. Se considerarmos a data 20 de dezembro de 2015, 20/12/2015 é um formato válido para nós mas inválido para os Estados Unidos; já a data 12/20/2015 é o contrário.
Para especificar o formato exato para realizar a conversão, podemos criar um model binder específico para a data, e no interior do mesmo fazer a formatação desejada para todas as datas que são recebidas em parâmetros dos serviços. Abaixo está o exemplo de como poderíamos codificar este formatador:
public class CustomDateTimeModelBinder : IModelBinder
{
private readonly string format;
public CustomDateTimeModelBinder(string format)
{
this.format = format;
}
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var date = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
if (string.IsNullOrWhiteSpace(date))
return false;
bindingContext
.ModelState
.SetModelValue(
bindingContext.ModelName,
bindingContext.ValueProvider.GetValue(bindingContext.ModelName));
DateTime result = DateTime.MinValue;
if (DateTime.TryParseExact(date, format, Thread.CurrentThread.CurrentCulture, DateTimeStyles.None, out result))
{
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(
bindingContext.ModelName,
string.Format(“”{0}” is invalid.”, bindingContext.ModelName));
return false;
}
}
Por fim, basta acoplá-lo à execução e indicar ao ASP.NET Web API que ele trata e valida o tipo DateTime. Para isso, basta utilizar a configuração do serviço para inclui-lo e as requisições que mandarem a data no formato especificado em seu construtor serão corretamente convertidas em DateTime respeitando o dia, mês e ano.
config.BindParameter(typeof(DateTime), new CustomDateTimeModelBinder(“dd/MM/yyyy”));