I manage to solve my problem using Model binding as suggested by @Jakotheshadows and @Amy.
I used the code from this answer about ModelBinders in Web Api with a few tweaks from this answer (it's in portuguese, but the code is clear).
So my code right now:
using System;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
namespace Site.Services
{
public class DateTimeModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
ValidateBindingContext(bindingContext);
if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) ||
!CanBindType(bindingContext.ModelType))
{
return false;
}
var modelName = bindingContext.ModelName;
var attemptedValue = bindingContext.ValueProvider
.GetValue(modelName).AttemptedValue;
try
{
bindingContext.Model = DateTime.Parse(attemptedValue);
}
catch (FormatException e)
{
bindingContext.ModelState.AddModelError(modelName, e);
}
return true;
}
private static void ValidateBindingContext(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
if (bindingContext.ModelMetadata == null)
{
throw new ArgumentException("ModelMetadata cannot be null", "bindingContext");
}
}
public static bool CanBindType(Type modelType)
{
return modelType == typeof(DateTime) || modelType == typeof(DateTime?);
}
}
}
I used try
and DateTime.Parse
as suggested in the second link, because the first always throwed an exception even with try and catch.
The ModelBinderProvider I used as he suggested:
using System;
using System.Web.Http;
using System.Web.Http.ModelBinding;
namespace Site.Services
{
public class DateTimeModelBinderProvider : ModelBinderProvider
{
readonly DateTimeModelBinder binder = new DateTimeModelBinder();
public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
{
if (DateTimeModelBinder.CanBindType(modelType))
{
return binder;
}
return null;
}
}
}
And I configure as suggested here (also an answer for the first link), but in my WebApiConfig.cs
(didn't work in Global.asax
), like this:
using Site.Services;
using System;
using System.Web.Http;
namespace Site
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.BindParameter(typeof(DateTime), new DateTimeModelBinder());
config.BindParameter(typeof(DateTime?), new DateTimeModelBinder());
//Rest of my code
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
I think the globalization
of the Web.config
, the uiCulture
and culture
must be set to the culture you want and enableClientBasedCulture
be set as true
as suggest here, but I'm not sure because I didn't want to change the code to test it.