将JObject转换成Dictionary <string,object>。 可能吗?

我有一个Web API方法,接受一个任意的JSON负载到一个JObject属性。 因此,我不知道会发生什么,但我仍然需要将其转换为.NETtypes。 我想有一个词典,所以我可以处理它,无论如何我想。

我search了很多,但无法find任何东西,并最终开始了一个混乱的方法来做这种转换,按键,价值的价值。 有没有简单的方法来做到这一点?

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)) ) ) 

谢谢!

如果您有JObject对象,以下可能会工作:

 JObject person; var values = person.ToObject<Dictionary<string, object>>(); 

否则, 这个答案可能会指向正确的方向,因为它将一个JSONstring反序列化为一个Dictionary。

 var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); 

我结束了使用两个答案的混合,因为没有真正钉牢它。

ToObject()可以在JSON对象中执行第一级属性,但嵌套对象不会被转换为Dictionary()。

也不需要手动完成所有的事情,因为ToObject()对于第一级属性来说是相当不错的。

这里是代码:

 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; } } 

它可能有边缘的情况下,它不会工作,性能不是最强的质量。

多谢你们!

以下是最初的版本:我已经修改了代码来recursionJArrays 嵌套在 JArrays / JObjects 中的 JObjects ,正如@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; } } 

听起来像扩展方法的一个很好的用例 – 我有东西躺在这是非常简单的转换为Json.NET(感谢NuGet!):

当然,这很快就会被破解 – 你要清理它,等等。

 public static class JTokenExt { public static Dictionary<string, object> Bagify(this JToken obj, string name = null) { name = name ?? "obj"; if(obj is JObject) { var asBag = from prop in (obj as JObject).Properties() let propName = prop.Name let propValue = prop.Value is JValue ? new Dictionary<string,object>() { {prop.Name, prop.Value} } : prop.Value.Bagify(prop.Name) select new KeyValuePair<string, object>(propName, propValue); return asBag.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } if(obj is JArray) { var vals = (obj as JArray).Values(); var alldicts = vals .SelectMany(val => val.Bagify(name)) .Select(x => x.Value) .ToArray(); return new Dictionary<string,object>() { {name, (object)alldicts} }; } if(obj is JValue) { return new Dictionary<string,object>() { {name, (obj as JValue)} }; } return new Dictionary<string,object>() { {name, null} }; } } 

这会将JObject / JArray / JValue树转换成Dictionary / List / object:

 static object Convert(JToken token) { switch (token) { case JObject obj: return new Dictionary<string, object>(obj.Properties().ToDictionary(pair => pair.Name, pair => Convert(pair.Value))); case JArray array: return new List<object>(array.Select(item => Convert(item))); case JValue value: return value.Value; } throw new NotSupportedException(); }