5

I am using Json.Net to deserialize json results into ExpandoObjects using code like the following:

    var converter = new ExpandoObjectConverter();

    dynamic d = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);

This works great for everything except responses that have only a list at the root of the json schema such as this:

string json = @"[{""title"": ""the title""}]";

In the bowels of JsonConvert is this method:

public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
{
    return (T)DeserializeObject(value, typeof(T), converters);
}

The return value DeserializeObject is a properly constructed List<object> with on ExpandoObject in it but the code fails trying to cast that list to an ExpandoObject itself (the value of T).

I've got a failing unit test and could fix this but am not sure how to stuff a List directly into an ExpandoObject.

Is this possible? DynamicObject has TryGetIndex so I assume an ExpandoObject can have an indexer. Would it be necessary to carefully construct a list-like instance of expando by dynamically supplying the implementation of an indexing method or otherwise create a non-expando DynamicObject to hold the list and invoke the correctly methods from dynamic method calls?

dkackman
  • 15,179
  • 13
  • 69
  • 123

1 Answers1

2

DynamicObject has TryGetIndex so I assume an ExpandoObject can have an indexer

No, it can't. Just try it, it returns a RuntimeBinderException:

Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject'

An ExpandoObject is not a list; it's more like a dictionary.

Would it be necessary to carefully construct a list-like instance of expando by dynamically supplying the implementation of an indexing method or otherwise create a non-expando DynamicObject to hold the list and invoke the correctly methods from dynamic method calls?

Well, you could create a custom DynamicObject that behaves like a list, but I don't see any benefit in doing that: you might as well use a normal list.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • I'm experimenting with a rest client that always returns dynamic objects. Only the outermost consumer code would know a list is expected if you know what I mean. So I'd have one code path for lists (client.GetList()) and another code path for everything else (client.Get()). Not the worst thing in the world I suppose. Json.Net's JObject can be a List but I am trying to avoid it as it has some other behaviors I'm not a fan of. – dkackman Jun 05 '14 at 00:23
  • And you were right. I needed to give JSonConvert the hint which is what I was missing: if (content.StartsWith("[")) return JsonConvert.DeserializeObject>(content, converter); return JsonConvert.DeserializeObject(content, converter); – dkackman Jun 05 '14 at 01:20