Problem deserializing object containing an IEnumerable

5,659 views
Skip to first unread message

Chris Nicola

unread,
Jan 25, 2011, 3:36:46 PM1/25/11
to RestSharp
This is the response JSON:
{"Id":"fb2dac20-8fa4-41b4-9138-
c13a7857e506","Account":"23C065FA-1E4C-484B-8B80-5FD19863254E","Name":"TestData1","Products":
["http://example.com/url-for-added-product"]}

And this is what I am deserializing it to.

public class MyClass
{
public Guid Id { get; set; }
public string Account { get; set; }
public string Name { get; set; }
public IEnumerable<string> Products { get; set; }
}

Everything deserializes fine except the Products, which are always
null. This doesn't make a lot of sense since I am also using
Newtonsoft to serialize the JSON that produced the response and it is
using exactly the same class in both cases. Any suggestions as to why
this is happening?

Thanks,
Chris

Andrew Young

unread,
Jan 25, 2011, 3:42:30 PM1/25/11
to rest...@googlegroups.com
For now it only deserializes List<> and no interface types of collections, IEnumerable<> or even IList<>.

See line 195 in JsonDeserializer.cs.

Hopefully this will get fixed soon?

Chris Nicola

unread,
Jan 25, 2011, 4:06:25 PM1/25/11
to RestSharp
Yikes. Is that a problem with Newtonsoft.Json or something or just a
result of the way Rest# works?

Chris

On Jan 25, 12:42 pm, Andrew Young <andrewdyo...@gmail.com> wrote:
> For now it only deserializes List<> and no interface types of collections,
> IEnumerable<> or even IList<>.
>
> See line 195 in JsonDeserializer.cs.
>
> Hopefully this will get fixed soon?
>
>
>
>
>
>
>
> On Tue, Jan 25, 2011 at 12:36 PM, Chris Nicola <chnic...@gmail.com> wrote:
> > This is the response JSON:
> > {"Id":"fb2dac20-8fa4-41b4-9138-
>
> > c13a7857e506","Account":"23C065FA-1E4C-484B-8B80-5FD19863254E","Name":"Test Data1","Products":

Stuart Grassie

unread,
Jan 25, 2011, 7:20:39 PM1/25/11
to rest...@googlegroups.com
Maybe John could confirm, but I'm of the opinion it's not a problem with Newtonsoft.Json, more perhaps just a scenario (in Rest#) that hasn't been implemented.

I think changing BuildList to something like this would achieve the desired functionality:

private T BuildList<T>(T type, JEnumerable<JToken> elements) where T : IEnumerable<T>
{
var list = Activator.CreateInstance<T>();
var itemType = type.GetGenericArguments()[0];
Then l195/197 could be changed accordingly. The only thing I'm a bit dubious on is the where constraint, I've a feeling it would let a Dictionary<T, V> through, and then BuildList would fail. So the constraint might not be necessary, and the test would have to be on l195 instead.

My caveat is that I've not tested any of this, and I've not got any time to write any unit tests for it. It's fairly late here now. If I get chance tomorrow, then I'll have a proper look at it (unless someone beats me to it).

Stu

Chris Nicola

unread,
Jan 25, 2011, 8:42:01 PM1/25/11
to rest...@googlegroups.com
Should it just be possible to directly deserialize to the desired type via Newtonsoft, or am I missing something important?

Andrew Young

unread,
Jan 25, 2011, 8:57:07 PM1/25/11
to rest...@googlegroups.com
Chris, I would like to know the answer to that as well.

Stuart Grassie

unread,
Jan 26, 2011, 3:40:24 AM1/26/11
to rest...@googlegroups.com
Looking at the Newtonsoft.Json docs, it looks to me that it should be possible to have it deserialize generic lists/dictionaries. http://james.newtonking.com/projects/json/help/

List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);


As to why Rest# doesn't use this, I'm not sure. I remember submitting a patch that was to do with deserializing into a generic list several months ago... perhaps I overlooked the capabilities of json.net at the time. Or it could be for another reason. When I get chance I'll write some unit tests and dig into it. Maybe John will have a more definite answer.

Stu

John Sheehan

unread,
Jan 26, 2011, 5:31:42 PM1/26/11
to rest...@googlegroups.com
You could take response.Content and feed it to JSON.NET, or wrap all
that up into a JsonNetDeserializer. The reason I don't use it directly
is because I didn't want to be tied to it long term and my element
matching logic is "magic" and much more flexible without any
configuration by default.

If I recall correctly it's based off of List because IEnumerable does
not have an Add() method and I didn't spend any time trying to figure
out how to get around that. I think IList<> would work (and that's
really how it should be) but beyond that, I'm happy to take
suggestions to make it more flexible.

John Sheehan

unread,
Jan 26, 2011, 5:34:32 PM1/26/11
to rest...@googlegroups.com
Also, the supported types are documented here:
https://github.com/johnsheehan/RestSharp/wiki/Deserialization

Andrew Young

unread,
Jan 28, 2011, 1:00:41 PM1/28/11
to rest...@googlegroups.com
John,

Re: deserializing IList<>. It doesn't work. It will pass the 'if' check on line 195 but will fail when trying to CreateInstance on line 260.

Just try something like this out and you'll get a System.MissingMethodException.  "Cannot create an abstract class..."

var list = Activator.CreateInstance(typeof(IList<string>));

This would make sense as it wouldn't know what concrete type of List<> to create.

Weston McNamee

unread,
Apr 6, 2014, 9:20:04 PM4/6/14
to rest...@googlegroups.com
I just submitted a pull request that will allow for deserialization of abstract classes and interfaces. Passing TinyIoCContainer to the JsonDeserializer object with the registrations of the concrete types that should be used when an interface or abstract class is seen with the target object.

https://github.com/restsharp/RestSharp/pull/525
Reply all
Reply to author
Forward
0 new messages