使用JavaScriptSerializer反序列化JSON字符串为expando?

4

我正在通过以下方式即时创建JSON对象(不需要 Json.net):

dynamic expando = new ExpandoObject();
expando.Age = 42;
expando.Name = "Royi";
expando.Childrens = new ExpandoObject();
expando.Childrens.First = "John"; 

这看起来像是:

在此输入图片描述

因此,我可以像这样查询它:

Console.WriteLine (expando.Name); //Royi

好的,那么让我们对其进行序列化:
var jsonString = new JavaScriptSerializer().Serialize(expando);
Console.WriteLine (jsonString);

结果:

[{"Key":"Age","Value":42},{"Key":"Name","Value":"Royi"},{"Key":"Childrens","Value":[{"Key":"First","Value":"John"}]}]

请注意,expando(即字符串、对象的Idictionary)正在保存数据

问题

现在我想将字符串反序列化回来:

enter image description here

我尝试过:

var jsonDeserizlied = new JavaScriptSerializer().Deserialize<ExpandoObject>(jsonString);

但是:

'System.Dynamic.ExpandoObject'类型不支持数组的反序列化。

那么,我应该怎么办才能得到

 [{"Key":"Age","Value":42},{"Key":"Name","Value":"Royi"},{"Key":"Childrens","Value":[{"Key":"First","Value":"John"}]}]

回到可扩展表示方式?

我们不使用JSON.net。

更新

我已成功将object[]更改为IList<IDictionary<string,object>>

 var jsonDeserizlied = new JavaScriptSerializer().Deserialize<IList<IDictionary<string,object>>>(jsonString);

现在的样子是: enter image description here 但是我需要将其转换为: enter image description here

这个答案对你有用吗?一旦它是一个对象,你就可以将其转换为expando,对吧? - oleksii
不行。在这里看为什么 http://i.imgur.com/1PnZ4T2.png (问题是由于数组结构引起的) - Royi Namir
你尝试过使用Dictionary<String, Object>而不是通过Expando进行反序列化吗?就像这样:var jsonDeserizlied = new JavaScriptSerializer().Deserialize<Dictionary<String, Object>>(jsonString); - Peter Smith
@PeterSmith http://i.imgur.com/EnAHA8o.png - Royi Namir
1
@RoyiNamir 啊...我明白你的意思了,它并不是将每个属性序列化到一个单独的字典中,而是将它们分解成了3个单独的字典。这似乎更多是与序列化程序生成JSON的方式有关,因为从技术上讲,您的JSON表示并没有表明它是一个单一的对象。您是否尝试先将您的ExpandoObject转换为Dictionary<string, object>,然后再进行反序列化为JSON呢? - James
显示剩余9条评论
1个回答

3

明白了。

首先,我们需要处理的是一个 IEnumerable<> 的 JSON 表示形式(因为 ExpandoObject 通过 JavaScriptSerializer 进行序列化)。所以:

var jsonDeserizlied = new   JavaScriptSerializer().Deserialize<IEnumerable<IDictionary<string,object>>>(jsonString);
 Console.WriteLine (jsonDeserizlied);

我还编写了这个递归函数,它可以递归地创建ExpandoObject和子级展开对象:
public ExpandoObject go( IEnumerable<IDictionary<string,object>> lst)
{

 return lst.Aggregate(new ExpandoObject(),
                           (aTotal,n) => {
                                (aTotal    as IDictionary<string, object>).Add(n["Key"].ToString(), n["Value"] is object[] ? go(  ((object[])n["Value"]).Cast<IDictionary<string,Object>>())  :n["Value"] );
                                return aTotal;
                           });

}

是的,我知道它还可以改进,但我只想展示这个想法。

现在我们通过以下方式调用它:

var tt=   go(jsonDeserizlied);

结果:

enter image description here

完全符合我的要求。

Console.WriteLine (tt.Age ); //52

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接