0

I have a nested data structure: Class A contains Class B contains Class C contains Class D.

Using JSON.NET, is there a way to "register" a custom deserializer for Class D only -- allowing the default deserializer to handle Classes A through C -- and then deserialize the entire data structure with a single method call to deserialize the root object of Class A?

Maybe I've misunderstood the API but so far the only potential approach in JSON.NET that I've found requires writing custom deserializers for all 4 Classes so that each can call the custom deserializer for the class nested within it (i.e., custom deserializer for A invokes custom deserializer for B, etc). This would entail a lot of work when all I really want is to customize how Class D is deserialized.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
skrilmps
  • 625
  • 2
  • 10
  • 29
  • What kind of customization you want to achieve? – Chetan Jan 20 '17 at 18:36
  • I think you're talking about [something like this](http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm)? – Heretic Monkey Jan 20 '17 at 18:40
  • @ChetanRanpariya The customization I want to achieve is that D is actually an Interface with two subtypes, D1 and D2, and I want to check to see which it is before deserializing. The way to do this particular type of customization is explained here: http://stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list-of-base So I know how to write the custom deserializer, but now I want to know how to "register" it so that it is invoked during deserialization while the default deserializer handles the rest of the data structure. – skrilmps Jan 20 '17 at 18:45
  • @MikeMcCaughan Thanks for the link. I am not sure whether it answers my question or not. I still want to deserialize the entire data stream. I just want the default deserializer to do most of the work while I only write the part that handles deserializing Class D. Does the link you provided explain how to accomplish that? Thanks! – skrilmps Jan 20 '17 at 18:49
  • 1
    Well, it tells you how to get specific parts of your JSON and deserialize just those parts. I suppose you could deserialize with the default deserializer, then fill in the "incorrectly" deserialized "Class D"s with your custom deserialized objects. That's deserializing twice, but I'm not sure how else to tell the default deserializer what class is what. Looks like [this question](http://stackoverflow.com/q/20406717/215552) is also asking something similar. – Heretic Monkey Jan 20 '17 at 18:54
  • @MikeMcCaughan Thanks. Looking at that question, I wonder if this is the line of code I'm looking for? `this.serializer.Converters.Add(new BusinessObjectCreationConverter());` , where `BusinessObjectCreationConverter` is their custom deserializer which extends `CustomCreationConverter<>` – skrilmps Jan 20 '17 at 19:30

1 Answers1

0

To specify a custom deserializer for JSON.NET to use for a particular class, you can do so with the JsonConverter Attribute. In the example from the question above, Class D's declaration might look like:

[JsonConverter(typeof(ClassDConverter))]
public class ClassD
{

}

where ClassDConverter is the custom deserializer and must extend JsonConverter:

public class ClassDConverter : JsonConverter
{
     public override object ReadJson(...)
     {
           // custom deserialization code here
     }

     public override bool CanConvert(Type objectType)
     {
          return typeof(ClassD).isAssignableFrom(objectType);
     }

     public override bool CanWrite
     {
         get { return false; }
     }
 }

CanWrite returns false because I want to write a deserializer only. If you also wanted it to serialize, you could override the WriteJson method.

Here is the relevant page from Newtonsoft's API docs: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeClass.htm

This website provides an example and additional details in the context of de/serializing an Enum: https://gooddevbaddev.wordpress.com/2013/08/26/deserializing-c-enums-using-json-net/

skrilmps
  • 625
  • 2
  • 10
  • 29