1

I'm closing this question without answer, because it's duplicate of this: Serializing null in JSON.NET

I'm writing a simple converter which reads null as DateTime.UtcNow and writes null as DateTime.UtcNow.ToString("o"). It could be like this:

public class NullableDateTimeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        //Console.WriteLine("object type: " + objectType.Name);
        return objectType == typeof(DateTime?);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value == null)
        {
            return DateTime.Now;
        }
        else
        {
            return (DateTime?)reader.Value;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            serializer.Serialize(writer, DateTime.UtcNow.ToString("o"));
        }
        else
        {
            serializer.Serialize(writer, ((DateTime?)value).Value.ToString("o"));
        }
    }
}

Now, I'm trying to serialize, and deserialize this object.

public class NullableDateTimeObject
{
    public DateTime? Value { get; set; }
}

Like this:

public static void Main()
{
    var settings = new JsonSerializerSettings();
    settings.NullValueHandling = NullValueHandling.Include;
    settings.DefaultValueHandling = DefaultValueHandling.Include;
    settings.Converters.Add(new NullableDateTimeConverter());

    Console.WriteLine("------- not null -------");
    var result1 = JsonConvert.SerializeObject(
        new NullableDateTimeObject { Value = DateTime.UtcNow },
        settings);
    Console.WriteLine(result1);

    Console.WriteLine("------- null -------");
    var result2 = JsonConvert.SerializeObject(
        new NullableDateTimeObject { Value = null },
        settings);
    Console.WriteLine(result2);

    Console.WriteLine("------- but it reads null -------");
    var resultRead = JsonConvert.DeserializeObject<NullableDateTimeObject>(
        "{\"Value\":null}",
        settings);
    Console.WriteLine(resultRead.Value);
}

I expected that the second one also writes ISO8601 datetime, but it writes null.

------- not null -------
{"Value":"2017-02-25T13:04:13.3091219Z"}
------- null -------
{"Value":null}
------- but it reads null -------
2/25/2017 1:14:56 PM

The JsonConverter doesn't even call CanConvert() override for a null value of property, when it serializes an object. In other hands, it works as I expected when it deserializes an object.

Does it an expected behavior? How can I make to use JsonConverter for a null value?

+I made a fiddle to reproduce it: https://dotnetfiddle.net/5PLvsk

[Added]

I also tested with explicit JsonConverter for the property, just in case, like this:

public class NullableDateTimeObjectWithExplicitConverter
{
    [JsonConverter(typeof(NullableDateTimeConverter))]
    [JsonProperty(IsReference = true, DefaultValueHandling = DefaultValueHandling.Populate, NullValueHandling = NullValueHandling.Include)]
    public DateTime? Value { get; set; }
}

Console.WriteLine("------- explicit converter -------");
var result3 = JsonConvert.SerializeObject(
    new NullableDateTimeObjectWithExplicitConverter { Value = null },
    settings);
Console.WriteLine(result3);

The result is same, null.

------- explicit converter -------
{"Value":null}

Even if the explicit one worked, but the JsonConverterSettings should be working recursively, I think.

Community
  • 1
  • 1
Gongdo Gong
  • 1,000
  • 7
  • 18
  • Correct me I'm wrong. But I think `reader.Value` should be a string. So `(DateTime?)reader.Value` will always be null. – Hoang Hiep Feb 25 '17 at 13:52
  • @AnyName problem is, it doesn't even call CanConvert and ReadJson override at all. So the code you mentioned is, never got a chance to be executed if the value was null. And no, JsonReader.Value is object, so it can be cast from null. – Gongdo Gong Feb 25 '17 at 14:20
  • I see. Take a look at [this question](http://stackoverflow.com/questions/8833961/serializing-null-in-json-net). Looks like they've got the same issue with you. – Hoang Hiep Feb 25 '17 at 14:55
  • Yes, this is how Json.NET works. When a value is `null`, it just calls [`JsonWriter.WriteNull()`](http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonWriter_WriteNull.htm) without calling any converter. (Notice that nobody ever checks for the value being null in `WriteJson()`? That's why.) But during reading the converter is called regardless of the contents of the current token, since Json.NET doesn't read or process the token -- the converter does. – dbc Feb 25 '17 at 15:01
  • @AnyName Oh, I couldn't find that one, that explains completely. Thanks. – Gongdo Gong Feb 25 '17 at 15:08

0 Answers0