强制 JSON.NET 在序列化 DateTime 时包含毫秒并为空日期字段输出空值

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

我在 Newtonsoft.Json 中遇到 DateTimeFormat 的问题。我要发布到的 API 需要所有日期的毫秒数。我正在序列化的对象有许多日期字段,其中一些对于某些数据为空。

我似乎无法让 JSON 为空日期输出空值并在具有日期的字段中包含毫秒数。我可以让一个或另一个工作,但不能同时工作。

很确定这是个小问题,但我还没有弄清楚,我已经花了几天时间研究它。

这会正确输出 null,但不包括毫秒数:

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);
    }
}

这是输出:

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

"dateOfDeath": null`

这会正确输出包括毫秒在内的日期,但空日期也会转换为 DateTime

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

这是输出:

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

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

我查看了以下两篇 SO 文章,但无法让它们协同工作。

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

非常感谢任何帮助。

问题是 MinDateTimeConverter 中的 ReadJsonWriteJson 方法没有调用基础 class,因此处理自定义日期格式的正常处理在非空情况下永远不会发生。这是更正后的代码:

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