When serializing arbitrary data through JSON.NET, any property that is null is written to JSON as
"propertyName": null
This is correct, of course.
However, I have a requirement to automatically set all zeros to the default value, equal to the default. null string should become String.Empty , null int? should become 0 , null bool? must be false , etc.
NullValueHandling doesn't help, since I don't want Ignore nulls, but I also don't want Include them (Hmm, new function?).
So, I turned to the implementation of custom JsonConverter .
While the implementation itself was easy, unfortunately, it still didn't work - CanConvert() never called for a property with a null value, so WriteJson() is not called either. Apparently, zeros are automatically serialized directly to null without a custom pipeline.
For example, here is an example of a custom converter for null strings:
public class StringConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(string).IsAssignableFrom(objectType); } ... public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { string strValue = value as string; if (strValue == null) { writer.WriteValue(String.Empty); } else { writer.WriteValue(strValue); } } }
When doing this in the debugger, I noticed that none of these methods were called for properties with a null value.
Getting into the JSON.NET source code, I found that (apparently, I did not deal with great depth) there is a special register for checking zeros and an explicit call to .WriteNull() .
For what it's worth, I tried to implement a custom JsonTextWriter and override the default implementation .WriteNull() ...
public class NullJsonWriter : JsonTextWriter { ... public override void WriteNull() { this.WriteValue(String.Empty); } }
However, this will not work, as the WriteNull() method does not know anything about the underlying data type. I am sure that I can output "" for any null value, but this does not work well, for example. int, bool, etc.
So my question is - do I need to convert the entire data structure manually, is there any solution or workaround for this?