I\'m writing a JsonConverter to perform some conversion tasks I need accomplished on read/write. In particular, I\'m taking the existing serialization behavior
This is a very common problem. Using "JsonConvert.SerializeObject" isn't a bad idea. However, one trick that can be used in some circumstances (typically collections) is to cast to the interface when writing and deserialize to a simple derivative when reading.
Below is a simple converter that deals with dictionaries that might have been serialized as a set of KVPs rather than looking like an object (showing my age here :) )
Note "WriteJson" casts to IDictionary< K,V> and "ReadJson" uses "DummyDictionary". You end up with the right thing but uses the passed serializer without causing recursion.
///
/// Converts a to and from JSON.
///
public class DictionaryAsKVPConverter : JsonConverter
{
///
/// Determines whether this instance can convert the specified object type.
///
/// Type of the object.
///
/// true if this instance can convert the specified object type; otherwise, false .
///
public override bool CanConvert(Type objectType)
{
if (!objectType.IsValueType && objectType.IsGenericType)
return (objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>));
return false;
}
///
/// Writes the JSON representation of the object.
///
/// The to write to.
/// The value.
/// The calling serializer.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dictionary = value as IDictionary;
serializer.Serialize(writer, dictionary);
}
///
/// Reads the JSON representation of the object.
///
/// The to read from.
/// Type of the object.
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Dictionary dictionary;
if (reader.TokenType == JsonToken.StartArray)
{
dictionary = new Dictionary();
reader.Read();
while (reader.TokenType == JsonToken.StartObject)
{
var kvp = serializer.Deserialize>(reader);
dictionary[kvp.Key] = kvp.Value;
reader.Read();
}
}
else if (reader.TokenType == JsonToken.StartObject)
// Use DummyDictionary to fool JsonSerializer into not using this converter recursively
dictionary = serializer.Deserialize(reader);
else
dictionary = new Dictionary();
return dictionary;
}
///
/// Dummy to fool JsonSerializer into not using this converter recursively
///
private class DummyDictionary : Dictionary { }
}