Convert JObject into Dictionary<string, object>. Is it possible?
If you have JObject
objects, the following might work:
JObject person;var values = person.ToObject<Dictionary<string, object>>();
If you do not have a JObject
you can create one with the Newtonsoft.Json.Linq
extension method:
using Newtonsoft.Json.Linq;var values = JObject.FromObject(person).ToObject<Dictionary<string, object>>();
Otherwise, this answer might point you in the right direction, as it deserializes a JSON string to a Dictionary.
var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
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!
Here's the inception version: I've modified the code to recurse JArrays an JObjects nested in JArrays/JObjects, which the accepted answer does not, as pointed out by @Nawaz.
using System.Collections.Generic;using System.Linq;using Newtonsoft.Json.Linq;public static class JsonConversionExtensions{ public static IDictionary<string, object> ToDictionary(this JObject json) { var propertyValuePairs = json.ToObject<Dictionary<string, object>>(); ProcessJObjectProperties(propertyValuePairs); ProcessJArrayProperties(propertyValuePairs); return propertyValuePairs; } private static void ProcessJObjectProperties(IDictionary<string, object> propertyValuePairs) { var objectPropertyNames = (from property in propertyValuePairs let propertyName = property.Key let value = property.Value where value is JObject select propertyName).ToList(); objectPropertyNames.ForEach(propertyName => propertyValuePairs[propertyName] = ToDictionary((JObject) propertyValuePairs[propertyName])); } private static void ProcessJArrayProperties(IDictionary<string, object> propertyValuePairs) { var arrayPropertyNames = (from property in propertyValuePairs let propertyName = property.Key let value = property.Value where value is JArray select propertyName).ToList(); arrayPropertyNames.ForEach(propertyName => propertyValuePairs[propertyName] = ToArray((JArray) propertyValuePairs[propertyName])); } public static object[] ToArray(this JArray array) { return array.ToObject<object[]>().Select(ProcessArrayEntry).ToArray(); } private static object ProcessArrayEntry(object value) { if (value is JObject) { return ToDictionary((JObject) value); } if (value is JArray) { return ToArray((JArray) value); } return value; }}