简体   繁体   中英

Deserialize json string back to expando using JavaScriptSerializer?

I'm creating a json object on the fly ( without Json.net ) via :

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

Which looks like :

在此输入图像描述

And so , I can query it like :

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

Ok , so let's serialize it :

var jsonString = new JavaScriptSerializer().Serialize(expando);
Console.WriteLine (jsonString);

Result :

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

Notice how expando ( which is Idictionary of string,object) is keeping data

Question

Now I want the string to be deserialized back to :

在此输入图像描述

I have tried :

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

But :

Type 'System.Dynamic.ExpandoObject' is not supported for deserialization of an array.

So , How can I get

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

back to expando representation ?

nb

we don't use JSON.net.

update

I have managed to change object[] to IList<IDictionary<string,object>> :

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

Which is now :

在此输入图像描述

but again , I need to transform it to :

在此输入图像描述

Got It.

First let's deal with the fact that it is an IEnumerable<> Json representation ( because of how ExpandoObject gets serialized via JavaScriptSerializer ) , so :

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

I've also written this recursive function which creates ExpandoObject and sub sub expandos recursively :

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

}

Yes , I know it can be improved but I just want to show the idea.

So now we invoke it via :

var tt=   go(jsonDeserizlied);

Result :

在此输入图像描述

Exactly What I wanted.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM