JSON Serialization in Web Api 2 not using ISO 8601 dates

16,321

Solution 1

Newtonsoft.Json defaults to IsoDateTimeConverter. So even if you do not specify anything, you should get the correct Iso format (and for me your code also works just fine btw.).

Read this or Scott's blog for further info about the defaults

You are most likely setting the converter somewhere else again, maybe you are using some custom converter with specific settings? Or are you using a very old version of Newtonsoft.Json?

Solution 2

Just a quick comment on @Toolkit's comment about the formatting.

The reason why you get a date string without the Z at the end is the datetime variable that you are parsing have the Kind as Unspecified.

It is likely that you are parsing a record coming from a database with a DateTime property, the database field lose the Kind once is saved.

This is why json is not adding the 'Z' at the end, it doesn't know if it is utc or local.

You can use a DatetimeOffset instead of Datetime, if you can change the model without too much impact. My option was to write a custom parser for Datetime and force it to be UTC if was not specified.

public class CustomJsonDateConverter : DateTimeConverterBase
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var date = DateTime.Parse(reader.Value.ToString());
        if (date.Kind == DateTimeKind.Unspecified)
        {
            date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
        }
        return date;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var date = (DateTime)value;
        if (date.Kind == DateTimeKind.Unspecified)
        {
            date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
        }
        writer.WriteValue(date);
    }
}

PD: I don't have enough points to write a comment, this isn't an answer to the main issue.

Share:
16,321
John Farrell
Author by

John Farrell

Updated on July 26, 2022

Comments

  • John Farrell
    John Farrell almost 2 years

    I'm using WebApi 2 to send some Json down to the client and its using the old style Date serialization and not ISO 8601.

    I'm seeing:

    "current_period_start": "\/Date(1388153705)\/",
    "current_period_end": "\/Date(1390832105)\/",
    "start": "\/Date(1388332525)\/",
    

    My Global.asax.cs looks like this:

            GlobalConfiguration.Configure(WebApiConfig.Register);
            var formatters = GlobalConfiguration.Configuration.Formatters;
            var jsonFormatter = formatters.JsonFormatter;
            var settings = jsonFormatter.SerializerSettings;
            settings.Converters.Add(new IsoDateTimeConverter());
            settings.Formatting = Formatting.Indented;
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    
  • John Farrell
    John Farrell over 10 years
    The problem ended up being the type, from a 3rd party assembly used, DateTime? and I never noticed until the date serialization issues I had.
  • Toolkit
    Toolkit over 8 years
    Web API returns '2016-01-01T00:00:00' which fails with ISO8601 Regex codepen.io/anon/pen/WryLGe fi i add Z at the end, it passes. codepen.io/anon/pen/qbKLaV
  • Zapnologica
    Zapnologica over 7 years
    @Toolkit so are you saying web api is not conforming to ISO8601?