So in case no items are found:
{
"items" : false
}
Otherwise:
{
"items" : [
{
"quantity": 2,
"name": "product"
},
{
"quantity": 2,
"name": "product"
}]
}
Default deserialization with JSON.Net doesn't seem to handle this very well. The obvious error message 'Cannot cast an instance of bool to a List of type 'item'' error is what I got.
So I wrote a custom converter that handles this case:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
///
/// This converter was created in order to cater with situations where
/// the JSON indicated 'false' in case an object was not present in the JSON.
///
/// This works well for weakly typed JavaScript but not as much for C#.
///
/// Example - trying to parse this JSON into a person class:
/// var person = {
/// name : 'John Doe',
/// childredn : false
/// }
///
/// var anotherPerson = {
/// name : 'Jane Doe',
/// children : [
/// { 'name' : 'Janine Doe' }
/// ]
/// }
///
/// This converter will return NULL in case 'false' is detected in code.
///
/// The underlying type instance - or NULL in case JSON states 'false'
public class FalseReturnsNullConverter : JsonConverter where T : new()
{
///
/// Serializes the instance as JSON
///
/// The JSON writer
/// The value to be serialized
/// The JSON serialized
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
///
/// Reads the JSON and converts it into:
/// - NULL in case value = 'false'
/// - An instance of T in case 'false' was not found
///
/// The JsonReader instance
/// The type of object
/// The existing value of the object
/// The JSON serializer
/// The deserialized instance
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Detect if the underlying value is 'false' - note that in case
// the reader finds the 'false' value - the underlying type of the reader.value object
// is a bool
var isNull = reader.Value is bool && (bool)reader.Value == false;
// In case the value is boolean false - return null, otherwise deserialize as usual
if (isNull)
{
return null;
}
// If not - business as usual
return serializer.Deserialize(reader);
}
///
/// Returns a value indicating whether the type can be converted using this
/// converter
///
/// The type of object which needs to be converted
/// True in case the underlying type can be converted using this converter
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
}
The only thing you need to do is place this attribute on top of the model so that JSON.Net knows to use this converter when deserializing this property:[JsonConverter(typeof(FalseReturnsNullConverter>))] public List
- offers { get; set; }
Easy enough and pretty elegant. It's generic too - so you should be able to use it with any underlying type.
No comments:
Post a Comment