I have a custom JsonConverter that interprets a json object that is a polymorphic class, and generates the correct subclass based on a child property.
public class Metadata // base class
public class MetadataText : Metadata
public class MetadataImage : Metadata
... etc
Each class with a child Metadata property has it marked as nullable:
public class Author
{
[CanBeNull] public Metadata metadata { get; set; }
}
This works fine for many variations of “metadata” in the incoming JSON. However… I have no control over the incoming json – huge files from a third party – and annoyingly they sometimes return “{}” where they should have returned “null”.
i.e.
...
"author":{
"metadata":
{}
}
…which SHOULD BE:
"author":{
"metadata": null
}
This seems to be generating a huge number of fake errors on deserialization (currently captured and logged to console using a custom error-handler)
var jsonSettings = new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
Error = HandleDeserializationError // just outputs the error
};
I can’t seem to find a way to get rid of those fake errors:
Value cannot be null.
Parameter name: value, path = [0].[OMITTED].author.metadata
class MetadataConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Metadata).IsAssignableFrom(objectType);
}
// has no effect: [CanBeNull]
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject item = JObject.Load(reader);
if( item.Count == 0 )
{
Debug.Log( "Found a Metadata with count = 0; "+reader.TokenType+", "+reader.Path+", "+reader.Value+" -- item: "+item.Type+", "+item.Parent?.Parent+", "+item.Path+", "+item.Properties().Count() );
return (Metadata)null; // should be OK!
}
switch (item["command"].Value<string>())
{
case "open_url": return item.ToObject<Metadata_OpenURL>();
case "search": return item.ToObject<Metadata_Search>();
case "mclick": return item.ToObject<Metadata_MClick>();
case "msearch": return item.ToObject<Metadata_MSearch>();
default: return item.ToObject<Metadata>();
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}