c# - Recursively call JsonSerializer in a JsonConverter -


i'm writing jsonconverter perform conversion tasks need accomplished on read/write. in particular, i'm taking existing serialization behavior , tacking on additional properties on write / reading additional properties on read.

inside jsonconverter, i'd make use of passed jsonserializer instance perform majority of conversion functionality. however, when this, end in recursive loop serializer calls converter calls serializer calls converter , etc.

i've seen people things such use jsonconvert.serializeobject, passing in converters serializer instance except this. however, won't work me because bypasses of other customization i've done on serializer, such custom contract resolver , datetime handling.

is there way can either:

  1. use serializer instance passed me, somehow exclude converter, or
  2. clone serializer passed me (without manually constructing new 1 , copying property property) , remove converter?

this common problem. using "jsonconvert.serializeobject" isn't bad idea. however, 1 trick can used in circumstances (typically collections) cast interface when writing , deserialize simple derivative when reading.

below simple converter deals dictionaries might have been serialized set of kvps rather looking object (showing age here :) )

note "writejson" casts idictionary< k,v> , "readjson" uses "dummydictionary". end right thing uses passed serializer without causing recursion.

/// <summary> /// converts <see cref="keyvaluepair{tkey,tvalue}"/> , json. /// </summary> public class dictionaryaskvpconverter<tkey, tvalue> : jsonconverter {     /// <summary>     /// determines whether instance can convert specified object type.     /// </summary>     /// <param name="objecttype">type of object.</param>     /// <returns>     ///     <c>true</c> if instance can convert specified object type; otherwise, <c>false</c>.     /// </returns>     public override bool canconvert(type objecttype)     {         if (!objecttype.isvaluetype && objecttype.isgenerictype)             return (objecttype.getgenerictypedefinition() == typeof(dictionary<,>));          return false;     }      /// <summary>     /// writes json representation of object.     /// </summary>     /// <param name="writer">the <see cref="jsonwriter"/> write to.</param>     /// <param name="value">the value.</param>     /// <param name="serializer">the calling serializer.</param>     public override void writejson(jsonwriter writer, object value, jsonserializer serializer)     {         var dictionary = value idictionary<tkey, tvalue>;         serializer.serialize(writer, dictionary);     }      /// <summary>     /// reads json representation of object.     /// </summary>     /// <param name="reader">the <see cref="jsonreader"/> read from.</param>     /// <param name="objecttype">type of object.</param>     /// <param name="existingvalue">the existing value of object being read.</param>     /// <param name="serializer">the calling serializer.</param>     /// <returns>the object value.</returns>     public override object readjson(jsonreader reader, type objecttype, object existingvalue, jsonserializer serializer)     {         dictionary<tkey, tvalue> dictionary;          if (reader.tokentype == jsontoken.startarray)         {             dictionary = new dictionary<tkey, tvalue>();             reader.read();             while (reader.tokentype == jsontoken.startobject)             {                 var kvp = serializer.deserialize<keyvaluepair<tkey, tvalue>>(reader);                 dictionary[kvp.key] = kvp.value;                 reader.read();             }         }         else if (reader.tokentype == jsontoken.startobject)             // use dummydictionary fool jsonserializer not using converter recursively             dictionary = serializer.deserialize<dummydictionary>(reader);         else             dictionary = new dictionary<tkey, tvalue>();          return dictionary;     }      /// <summary>     /// dummy fool jsonserializer not using converter recursively     /// </summary>     private class dummydictionary : dictionary<tkey, tvalue> { } } 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -