I have a collection class that implements IEnumerable and I am having trouble deserializing a serialized version of the same. I am using Json.net v 4.0.2.13623
Here
I believe JSON .NET depends on having a parameterless constructor for the types it deserializes to. From a deserialization point of view it has no idea what to provide to the constrcutor.
As for your collection, again how is it supposed to know how to populate an implementation of IEnumerable<T>
which only defines how to enumerate the collection not how to populate it. You should instead deserialize directly to some standard IEnumerable<MyType>
(or directly to IEnumerable<MyType>
which I believe JSON.NET supports) and then pass it to your constructor.
I believe all of the following should work in this case:
var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject<MyTypes[]>(_jsonContent));
var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject<List<MyTypes>>(_jsonContent));
var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject<IEnumerable<MyTypes>>(_jsonContent));
Alternatively, though more work, if you need to deserialized directly you can implement something like IList on your collection which should allow JSON.NET to use the IList methods to populate your collection.
As of Json.NET 6.0 Release 3 and later (I tested on 8.0.3), this works automatically as long as the custom class implementing IEnumerable<MyType>
has a constructor that takes an IEnumerable<MyType>
input argument. From the release notes:
To all future creators of immutable .NET collections: If your collection of T has a constructor that takes IEnumerable then Json.NET will automatically work when deserializing to your collection, otherwise you're all out of luck.
Since the MyTypes
class in the question has just such a constructor, this now just works. Demonstration fiddle: https://dotnetfiddle.net/LRJHbd.
Absent such a constructor, one would need to add a parameterless constructor and implement ICollection<MyType>
(instead of just IEnumerable<MyType>
) with a working Add(MyType item)
method. Json.NET can then construct and populate the collection. Or deserialize to an intermediate collection as in the original answer.