I have a requirement to deserialize JSON where the sender can send either a single instance of Child
as one of the nodes, or a Child[]
. (a.k.a JsonSchema 'oneOf`).
public class Parent
{
public Child[] Data { get; set; }
}
public class Child
{
public string ChildName { get; set; }
}
Where the JSON can be either an array
{
"data":
[
{
"childName": "Bob"
}
]
}
or a single object
{
"data":
{
"childName": "Bob"
}
}
This is what I have so far
public class ObjectToArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T[]);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartObject)
{
JObject singleJObject = (JObject)serializer.Deserialize(reader);
return new T[] { singleJObject.Value<T>() };
}
var arrayJObject = (JObject)serializer.Deserialize(reader);
return arrayJObject.Value<T[]>();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Which I use like so
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ObjectToArrayConverter<Child>());
var parent = JsonConvert.DeserializeObject<Parent>(json, settings);
But when the JSON data
node is a single object, the line return new T[] { jObject.Value<T>() };
gives me the exception
System.InvalidCastException: 'Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken.'
And when the JSON data
node is an array of objects, the line var arrayJObject = (JObject)serializer.Deserialize(reader);
gives me the exception
System.InvalidCastException: 'Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'Newtonsoft.Json.Linq.JObject'.