Artur Keyan
Artur Keyan

Reputation: 7683

Web Api DateTime not binding from JSON

This is my Model

public class PersonVModel
{
    [Required]
    public string FirstName { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime BirthDate { get; set; }
}

and here is my JSON

{
    "FirstName": "Artur",
    "BrithDate": "4/22/1991"
}

The strings, bools, and integers bind's well, but DateTime don't enter image description here

I have tried with [DataType(DataType.Date)] attribute too, it doesn't work too.

Any solutions?

Upvotes: 0

Views: 3696

Answers (2)

Pavel Voronin
Pavel Voronin

Reputation: 13983

You have a typo : "BrithDate" vs "BirthDate"

By default MVC model binder just sets properties to default values when binding fails. You can check model validity with IsValid property.

We created special filter which throws exception with the information where binding failed. It helps a lot with AngularJS and mistypings.

public class RequireValidModel : ActionFilterAttribute
{
    /// <summary>
    /// Called by the ASP.NET MVC framework before the action method executes.
    /// </summary>
    /// <param name="filterContext">The filter context.</param>
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        ModelStateDictionary state = filterContext.Controller.ViewData.ModelState;

        if (!state.IsValid)
        {
            var perPropertyMessages = state.Where(kvp => kvp.Value.Errors.Count > 0)
                                           .Select(kvp =>
                                               new
                                               {
                                                   Property = kvp.Key,
                                                   Value = kvp.Value.Value != null ? kvp.Value.Value.AttemptedValue: null,
                                                   ErrorMessages = kvp.Value.Errors.Select(err => err.Exception != null ? err.Exception.Message : err.ErrorMessage)
                                               })
                                           .Select(propertyErrors =>
                                               new
                                               {
                                                   propertyErrors.Property,
                                                   propertyErrors.Value,
                                                   ErrorMessages = string.Join("\n", propertyErrors.ErrorMessages)
                                               })
                                           .Select(
                                               propertyErrors =>
                                                   string.Format("(property: {0}, attempted value: {1}, errors: {2}\n)", propertyErrors.Property,
                                                       propertyErrors.Value, propertyErrors.ErrorMessages));

            var finalMessage = string.Format("Invalid model state:\n{0}", string.Join(",\n", perPropertyMessages));

            throw new InvalidOperationException(finalMessage);
        }
    }
}

Next, to avoid problems with dates, convert all date strings to Date objects at the very place where data is received.

Upvotes: 3

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131364

Your Json contains a US-specific date string, which is why it isn't recognized as a valid date. This string would also cause issues with any C# code that didn't run with a US locale.

While JSON itself doesn't specify a date type, everyone nowadays uses Javascript's ISO8601 format, eg: "2012-04-21T18:25:43-05:00Z"

Upvotes: 3

Related Questions