4

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 :

enter image description here

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 :

enter image description here

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 :

enter image description here

but again , I need to transform it to :

enter image description here

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Will [this answer](http://stackoverflow.com/a/13642873/706456) work for you? Once it's an object you can then convert it to expando, right? – oleksii Apr 22 '15 at 09:44
  • no. see here why http://i.imgur.com/1PnZ4T2.png ( The problem is becuase Array structure) – Royi Namir Apr 22 '15 at 09:45
  • Rather then deserialising through Expando have you tried `Dictionary`? As in `var jsonDeserizlied = new JavaScriptSerializer().Deserialize>(jsonString);` – Peter Smith Apr 22 '15 at 09:46
  • @PeterSmith I believe it's the same thing. Expando implements IDictionary, – Royi Namir Apr 22 '15 at 09:47
  • @PeterSmith http://i.imgur.com/EnAHA8o.png – Royi Namir Apr 22 '15 at 09:49
  • I believe ToDictionary is needed here. – Royi Namir Apr 22 '15 at 09:50
  • @James No. http://i.imgur.com/AyONzxV.png – Royi Namir Apr 22 '15 at 09:55
  • @RoyiNamir I think you will ultimately need to rebuild your `ExpandoObject` from your dictionary, here's one [example](https://gist.github.com/theburningmonk/2221646) of how that can be done. – James Apr 22 '15 at 09:55
  • @James look here http://i.imgur.com/Ft0Gqc6.png .I believbe simgle line of Linq code can transform it to dictionary. – Royi Namir Apr 22 '15 at 09:56
  • @RoyiNamir I'm confused, your question suggests you already have it serialized as a `Dictionary`, aren't you now looking for a way to convert it back to `ExpandoObject`? – James Apr 22 '15 at 09:58
  • @James Expando or dictionary , it doesnt matter. If I have it as single Idictionary then I could cast it to expando. Exapmle : If I have `var t=(IDictionary)expando;` then I will be able to do : `ExpandoObject lll = (ExpandoObject)t;` . but Look how messy is http://i.stack.imgur.com/JOef2.png . it is not a single object which I can treat it as single key value – Royi Namir Apr 22 '15 at 10:01
  • 1
    @RoyiNamir ah... I see what you mean, it's not serialized each property in a *single* dictionary, it's broken them down into 3 separate ones. That would appear more an issue with how the serializer generates the JSON because, technically, the representation of your JSON isn't suggesting it's a single object. Have you tried casting your `ExpandoObject` to `Dictionary` first and *then* deserializing to JSON? – James Apr 22 '15 at 10:06
  • My though on this is that your are wanting to deserialize into a dynamic object without knowing what that structure of the object is. For me, this implies two options. One - define a class to hold the object rather than Expando, OR - write a generic method to build your dynamic structure. This would recursively iterate through the List; if the value is a value type then stay at the same level (an Expando value); if the value is an object then you need a new level (an Expando child).. – Peter Smith Apr 22 '15 at 10:44

1 Answers1

3

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 :

enter image description here

Exactly What I wanted.

Console.WriteLine (tt.Age ); //52
Royi Namir
  • 144,742
  • 138
  • 468
  • 792