tucaz tucaz - 6 months ago 54
C# Question

Convert JObject into Dictionary<string, object>. Is it possible?

I have a web api method that accepts an arbitrary json payload into a JObject property. As such I don't know what's coming but I still need to translate it to .NET types. I would like to have a Dictionary so I can deal with it anyway I want to.

I searched a lot, but couldn't find nothing and ended up starting a messy method to do this conversion, key by key, value by value. Is there a easy way to do it?

Input ->

JObject person = new JObject(
new JProperty("Name", "John Smith"),
new JProperty("BirthDate", new DateTime(1983, 3, 20)),
new JProperty("Hobbies", new JArray("Play footbal", "Programming")),
new JProperty("Extra", new JObject(
new JProperty("Foo", 1),
new JProperty("Bar", new JArray(1, 2, 3))



I ended up using a mix of both answers as none really nailed it.

ToObject() can do the first level of properties in a JSON object, but nested objects won't be converted to Dictionary().

There's also no need to do everything manually as ToObject() is pretty good with first level properties.

Here is the code:

public static class JObjectExtensions
    public static IDictionary<string, object> ToDictionary(this JObject @object)
        var result = @object.ToObject<Dictionary<string, object>>();

        var JObjectKeys = (from r in result
                           let key = r.Key
                           let value = r.Value
                           where value.GetType() == typeof(JObject)
                           select key).ToList();

        var JArrayKeys = (from r in result
                          let key = r.Key
                          let value = r.Value
                          where value.GetType() == typeof(JArray)
                          select key).ToList();

        JArrayKeys.ForEach(key => result[key] = ((JArray)result[key]).Values().Select(x => ((JValue)x).Value).ToArray());
        JObjectKeys.ForEach(key => result[key] = ToDictionary(result[key] as JObject));

        return result;

It might have edge cases where it won't work and the performance is not the strongest quality of it.

Thanks guys!