0

When serializing an object, I have a List<T> property where T is an abstract type which I'd like to serialize naturally. However, when deserializing the object, I want/need to manually deserialize this abstract list. I'm doing the latter part with a custom JsonConverter which looks at a property on each item in the list and then deserializes it to the correct type and puts it in the list.

But I also need to deserialize the rest of the object, without doing it property-by-property. Pseudo-code follows.

MyObject

class MyObject {
    public Guid Id;
    public string Name;
    public List<MyAbstractType> Things;
}

MyObjectConverter

class MyObjectConverter : JsonConverter {
    public override object ReadJson(reader, ..., serializer) {
        // Line below will fail because the serializer will attempt to deserlalize the list property.
        var instance = serializer.Deserialize(reader);
        var rawJson = JObject.Load(reader); // Ignore reading from an already-read reader.

        // Now loop-over and deserialize each thing in the list/array.
        foreach (var item in rawJson.Value<JArray>(nameof(MyObject.Things))) {
            var type = item.Value<string>(nameof(MyAbstractType.Type));
            MyAbstractType thing;

            // Create the proper type.
            if (type == ThingTypes.A) {
                thing = item.ToObject(typeof(ConcreteTypeA));
            }   
            else if (type == ThingTypes.B) {
                thing = item.ToObject(typeof(ConcreteTypeB));
            }

            // Add the thing.
            instance.Things.Add(thing);
        }

        return instance;
    }
}

To recap, I want to manually handle the deserialization of Things, but allow them to naturally serialize.

Josh M.
  • 26,437
  • 24
  • 119
  • 200
  • Shouldn't it work by implementing [`CanConvert`](http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConverter_CanConvert.htm) and the manual reader? – Icepickle May 04 '17 at 21:07
  • If I understand you right the problem is you didn't returned the correct value at `CanConvert`, you must return only true when the `Type` passed to it is of the type your deserializer will handle, in this case `MyAbstractType`, if you do it this way the deserializer will be only called when an instance of `MyAbstractType` is going to be read from the JSON, the rest of the object will be deserailized as usual. – Gusman May 04 '17 at 21:07
  • Why are you applying the converter to `MyObject`? You could instead apply the converter to `MyAbstractType` and follow the instructions from [How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?](https://stackoverflow.com/q/8030538/3744182) or [Deserializing polymorphic json classes without type information using json.net](https://stackoverflow.com/q/19307752/3744182). – dbc May 05 '17 at 01:52
  • Also, your question is a little confusing. Are you asking how to deserialize or serialize? If serialize, it's a duplicate of [How to use default serialization in a custom JsonConverter](https://stackoverflow.com/q/29616596/3744182) – dbc May 05 '17 at 01:56
  • @dbc Your comment "you could instead apply the converter to `MyAbstractType`" was the answer. If you add it as an answer, I'll accept it. Thanks. – Josh M. May 05 '17 at 13:08

0 Answers0