lyneca
lyneca

Reputation: 31

Deserializing a class with a generic type parameter using JsonConvert in C#

I have a somewhat complex class hierarchy which I am attempting to deserialize using JsonConvert.

This is an extremely contrived example of what I'm trying to do. Note that:

Classes

namespace Animals {
    // cannot modify these
    public class Deserializable {}
    abstract class Region {}
    public class Africa : Region {}
    public class America : Region {}
    public class Europe : Region {}
    public class Australia : Region {}

    // can modify these
    public abstract class Animal : Deserializable {}
    public class Cow<T> : Animal where T : Region {}
    public class AngusCow : Cow<Australia> {}
    public class AurochCow : Cow<Europe> {}
    // I don't know any other cow types
}

The JSON I'm trying to deserialize

[
    { "$type": "Animals.AngusCow, Animals" },
    { "$type": "Animals.AurochCow, Animals" },
]

Deserialization Options

JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
serializerSettings.TypeNameHandling = TypeNameHandling.Auto;
serializerSettings.Formatting = Formatting.Indented;
serializerSettings.MaxDepth = new int?(50);
serializerSettings.ContractResolver = JsonSerializer.CreateDefault().ContractResolver;

The deserialization code:

var animals = JsonConvert.DeserializeObject<List<Deserializable>>(jsonString, serializerSettings);

My guess is that it's the Cow<T> part that's tripping it up, or maybe Cow<Australia>. Is there anything I need to put in the JSON itself to fix this? It's possible I could write this code without it needing the type parameter, but in my case I would prefer it to use one if I can.

The error is this:

Error resolving type specified in JSON 'Animals.AngusCow, Animals'.

And this is using the Json.NET library.

I can confirm that there is nothing wrong with the assembly name or even the type name, as in my actual code I have other 'Animals' contained within the json list - ones that don't have type parameters such as the Cow<T> - and they deserialize fine when the breaking types are not included in the list.


Edit: After further investigation, I removed the type parameter from Cow. I still ran into the same error.

For perhaps a simple example, the class hierarchy is:

Deserializable > A > B > X: Works
Deserializable > A > B > Y: Works
Deserializable > A > B > Z: Works
Deserializable > A > B > C > D: Does not work
Deserializable > A > B > C > E: Does not work
Deserializable > A > B > C > F: Does not work

Where A, B and C are all abstract.

This points to C being the problem class, however, C doesn't have any fields on it - so there can't be any problems with field deserialization.

Upvotes: 2

Views: 492

Answers (1)

lyneca
lyneca

Reputation: 31

This was caused by a typo in the class namespace (in the C# files).

Upvotes: 1

Related Questions