guytz72
guytz72

Reputation: 419

Force JSON.NET to include milliseconds AND output null for a null date field when serializing DateTime

I am having trouble with DateTimeFormat in Newtonsoft.Json. The API that I am publishing to requires milliseconds on all of the dates. The object I am serializing has a number of date fields, and some of these are null for some of the data.

I can't seem to get the JSON to output both null for the null dates AND inlucde the milliseconds in the fields that have dates. I can get one or other working, but not both together.

Pretty sure it is something small, but I've not managed to get to the bottom of it and I've spent a few days at it.

This correctly outputs null, but does not include milliseconds:

public string ToJson()
{   
    return JsonConvert.SerializeObject(this, new MinDateTimeConverter()).ToString();
}
    
public class MinDateTimeConverter : IsoDateTimeConverter
{
    public MinDateTimeConverter()
    {
        DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'";
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null)
            return DateTime.MinValue;

        return (DateTime)reader.Value;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        DateTime dateTimeValue = (DateTime)value;
        if (dateTimeValue == DateTime.MinValue)
        {
            writer.WriteNull();
            return;
        }

        writer.WriteValue(value);
    }
}

This is the output:

"dateOfBirth": "1943-03-02T00:00:00Z",  

"dateOfDeath": null`

This correctly outputs dates including milliseconds, but null dates are converted to a DateTime as well:

public string ToJson()
{           
    return JsonConvert.SerializeObject(this, new IsoDateTimeConverter() { DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'" }).ToString();
}

This is the output:

"dateOfBirth": "1943-03-02T00:00:00.000Z",

"dateOfDeath": "0001-01-01T00:00:00.000Z"   

I've looked at both the below SO articles but can't get them to work together.

Force JSON.NET to include milliseconds when serializing DateTime (even if ms component is zero)

JSON.NET Serialize DateTime.MinValue as null

Any help greatly appreciated.

Upvotes: 2

Views: 619

Answers (1)

Brian Rogers
Brian Rogers

Reputation: 129787

The issue is that the ReadJson and WriteJson methods in your MinDateTimeConverter do not call the base class, so the normal processing that handles the custom date format in the non-null case never happens. Here is the corrected code:

public class MinDateTimeConverter : IsoDateTimeConverter
{
    public MinDateTimeConverter()
    {
        DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'";
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType == typeof(DateTime) && reader.TokenType == JsonToken.Null)
            return DateTime.MinValue;

        return base.ReadJson(reader, objectType, existingValue, serializer);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value is DateTime date && date == DateTime.MinValue)
        {
            writer.WriteNull();
            return;
        }
        
        base.WriteJson(writer, value, serializer);
    }
}

Fiddle: https://dotnetfiddle.net/x8PAzf

Upvotes: 1

Related Questions