基本上我想做的是将一个级别的JSON(最初是顶级)反序列化为ExpandoObject,但是将该级别的所有属性(发现是数组)转换为JSON字符串(而不是将它们递归反序列化为列表)自己的。)
是这样的:
p.x_range.group_padding = 1.0
会生成一个ExpandoObject,它是一个List
[
{
"id": 1,
"name": "one",
"contacts": [
{ "name": "john", "email":"john@somewhere.com" },
{ "name": "jane", "email":"jane@somewhere.com" }
]
},
{
"id": 2,
"name": "two",
"contacts": [
{ "name": "jess", "email":"jess@somewhere.com" },
{ "name": "jenn", "email":"jenn@somewhere.com" }
]
}
]
答案 0 :(得分:0)
这不是一个常见的用例,因此我不知道对此有任何现有的支持。
我将使用Json.NET的LINQ到JSON,然后在填充ExpandoObject
时将所需的内容转换为。这是一个适用于您的示例数据的示例:
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
class Test
{
static void Main()
{
string json = File.ReadAllText("test.json");
JArray top = JArray.Parse(json);
var expandos = top
.Cast<JObject>()
.Select(ConvertToExpando)
.ToList<dynamic>();
Console.WriteLine(expandos[0].id); // 1 (as an Int64)
Console.WriteLine(expandos[0].name); // one
Console.WriteLine(expandos[0].contacts); // JSON
}
static ExpandoObject ConvertToExpando(JObject jobject)
{
var expando = new ExpandoObject();
IDictionary<string, object> dictionary = expando;
foreach (var pair in jobject)
{
dictionary[pair.Key] = ConvertValue(pair.Value);
}
return expando;
object ConvertValue(JToken token)
{
switch (token)
{
case JArray array:
return array.ToString();
case JValue value:
return value.Value;
default:
throw new Exception($"Can't handle {jobject.GetType()} yet");
}
}
}
}
答案 1 :(得分:0)
作为Json.Linq选项的替代方法,如果您不介意一点点开销,则可以让整个反序列化发生,然后遍历每个ExpandoObject作为Dictionary来替换集合属性,例如:>
List<ExpandoObject> expandoList = JsonConvert.DeserializeObject<List<ExpandoObject>>(jsonString, new ExpandoObjectConverter());
foreach (ExpandoObject expando in expandoList) {
IDictionary<string, object> expandoDict = expando as IDictionary<string, object>;
if (expandoDict != null) {
foreach (KeyValuePair<string, object> kvp in expandoDict) {
if (typeof(IEnumerable<Object>).IsAssignableFrom(kvp.Value.GetType())) {
expandoDict[kvp.Key] = JsonConvert.SerializeObject(kvp.Value);
}
}
}
}