Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON Serialization in Web Api 2 not using ISO 8601 dates

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();
like image 692
John Farrell Avatar asked Dec 29 '13 16:12

John Farrell


2 Answers

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?

like image 112
MichaC Avatar answered Jan 02 '23 05:01

MichaC


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.

like image 26
Jesus Mogollon Avatar answered Jan 02 '23 05:01

Jesus Mogollon