How to deserialize JSON to Dictionary<string, class>, where keys are unknown prior?

17,591 views
Skip to first unread message

Ryan Cole

unread,
Dec 21, 2013, 10:24:07 PM12/21/13
to rest...@googlegroups.com

I'm using the latest version of RestSharp, from NuGet. I'm querying an API that returns a JSON dictionary in which the keys cannot be hard coded into a C# class before-hand. The keys are not known, coming from the API.

I'm following the recommended usage pattern outlined on the RestSharp Wiki here:https://github.com/restsharp/RestSharp/wiki/Recommended-Usage.

I tried calling Execute so that it looks like this: Execute>(request). This throws an error saying that it cannot convert a JSON array into that Dictionary, though. The exact exception is as follows ...

Unable to cast object of type 'RestSharp.JsonArray' to type
'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

And the HTTP response from the API looks like this ...

{
  "108" : {
    "name" : "Malzahar's Captains",
    "tier" : "SILVER",
    "queue" : "RANKED_SOLO_5x5"
  }
}

Any ideas?

Brett Ryan

unread,
Dec 22, 2013, 12:26:31 AM12/22/13
to rest...@googlegroups.com
Hi Ryan, when you try to deserialize are you specifying an object type of just `object` or are you giving a type? Or, are what you saying is that the value object for the dictionary has unknown keys?

There are two ways to deserialize a dictionary string. If you know the return type (Widget) then it can be achieved with the following:

    class Widget {
        public string ID {
            get;
            set;
        }
    }

    string inp = "{\"a\": {\"id\": \"1\"}, \"b\": {\"id\":\"2\"}}";
    Dictionary<string, Widget> res1 = SimpleJson.DeserializeObject<Dictionary<string, Widget>>(inp);


However, if the properties of `Widget` are not known at runtime you can deserialize the values to another dictionary:

    string inp = "{\"a\": {\"id\": \"1\"}, \"b\": {\"id\":\"2\"}}";
    Dictionary<string, Dictionary<string, object>> res
        = SimpleJson.DeserializeObject<Dictionary<string, Dictionary<string, object>>>(inp);


Note that I am using `SimpleJson` here directly for demonstration only.

Ryan Cole

unread,
Dec 22, 2013, 10:32:05 AM12/22/13
to rest...@googlegroups.com
Sorry about the ambiguity. No, I'm not explicitly specifying `object`, I'm specifying a POCO of mine, called `League`, for example. In most of these queries, the API returns a documented key-value format that I can easily (automatically with RestSharp) deserialize into my POCOs. For this one particular query though, it's returning a dictionary of string-to-League objects, where the string key is the name of the League. (League is a term used in this computer game) The League names are user created, and therefor will change based on whose data you're asking for. So, I can't map it to a POCO of mine, like the other queries.


--
You received this message because you are subscribed to a topic in the Google Groups "RestSharp" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/restsharp/38x3tR1KztA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to restsharp+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Ryan Cole

unread,
Dec 22, 2013, 10:35:54 AM12/22/13
to rest...@googlegroups.com
Sent last email before I was finished, Oops.

My scenario is like your first example. It's a string mapping to Widget, basically. I know the properties of Widget, I just don't know the string keys. I think I'm doing the equivalent of your SimpleJson line. My current code is visible on Github, with these specific lines highlighted here and here ...


Thanks,
Ryan

Ryan Cole

unread,
Dec 22, 2013, 9:09:54 PM12/22/13
to rest...@googlegroups.com
Well, I can't figure it out. I'm trying to deserialize to Dictionary<String, Widget>, for example, and I'm not getting any errors. It's not parsing anything, though. Data is always null. I can see the JSON in the response, so the request went through just fine.

Ryan

ThanosS

unread,
Dec 26, 2013, 10:27:16 AM12/26/13
to rest...@googlegroups.com
{
  "108" : {
    "name" : "Malzahar's Captains",
    "tier" : "SILVER",
    "queue" : "RANKED_SOLO_5x5"
  }
}


You can use Json2C# which convert a json response to a data class. Here is the link : http://json2csharp.com/
When you type the json response you get, Json2C# say :

 
public class __invalid_type__108
{
    public string name { get; set; }
    public string tier { get; set; }
    public string queue { get; set; }
}

public class RootObject
{
    public __invalid_type__108 __invalid_name__108 { get; set; }
}

Ryan Cole

unread,
Dec 26, 2013, 1:15:40 PM12/26/13
to rest...@googlegroups.com
The result of JSON2C# contains a hard coded property name, though. This dictionary returned from the API cold conceivably have many other keys, as opposed to just "108". I think I need something along the lines of a more dynamic Dictionary<String, __invalid_type__108>, for example.

I've tried using a Dictionary<String, MyType> though and it fails to deserialize to it. The Data property is always null. Might this be a bug with RestSharp?

Chintan Prajapati

unread,
Apr 11, 2014, 1:23:55 AM4/11/14
to rest...@googlegroups.com
I am having same problem. 

Did anyone figureout solution ?

Chintan Prajapati

unread,
Apr 11, 2014, 9:29:14 AM4/11/14
to rest...@googlegroups.com
Finally i figured out how to correctly deserialize JSON to Dictionary<string, class>, where keys are unknown prior

I have blogged about it with example here

Hope it helps.

Sam Bill

unread,
Dec 23, 2021, 7:40:27 AM12/23/21
to RestSharp
Thanks, Chintan for sharing such a nice blog post. It was very useful for my website.
Reply all
Reply to author
Forward
0 new messages