Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flatten an ExpandoObject returned via JsonResult in asp.net mvc?

I really like the ExpandoObject while compiling a server-side dynamic object at runtime, but I am having trouble flattening this thing out during JSON serialization. First, I instantiate the object:

dynamic expando = new ExpandoObject(); var d = expando as IDictionary<string, object>; expando.Add("SomeProp", SomeValueOrClass); 

So far so good. In my MVC controller, I want to then send this down as a JsonResult, so I do this:

return new JsonResult(expando); 

This serializes the JSON into the below, to be consumed by the browser:

[{"Key":"SomeProp", "Value": SomeValueOrClass}] 

BUT, what I'd really like is to see this:

{SomeProp: SomeValueOrClass} 

I know I can achieve this if I use dynamic instead of ExpandoObject -- JsonResult is able to serialize the dynamic properties and values into a single object (with no Key or Value business), but the reason I need to use ExpandoObject is because I don't know all of the properties I want on the object until runtime, and as far as I know, I cannot dynamically add a property to a dynamic without using an ExpandoObject.

I may have to sift through the "Key", "Value" business in my javascript, but I was hoping to figure this out prior to sending it to the client. Thanks for your help!

like image 944
TimDog Avatar asked Mar 01 '11 15:03

TimDog


People also ask

How to flatten the Expando object in MVC?

Using JSON.NET you can call SerializeObject to "flatten" the expando object: dynamic expando = new ExpandoObject (); expando.name = "John Smith"; expando.age = 30; var json = JsonConvert.SerializeObject (expando); In the context of an ASP.NET MVC Controller, the result can be returned using the Content-method:

How to return a JSON from an Expando action?

First the ExpandoJsonResult, which you can return an instance of in your action. Or you can override the Json method in your controller and return it there.

What is jsonresult in MVC?

The JSON format is an open standard format. It’s a very familiar and commonly used concept. It’s a data interchange medium and is very lightweight. Developers use different JSON types for data transformation. JsonResult is an ActionResult type in MVC. It helps to send the content in JavaScript Object Notation (JSON) format.

How to return JSON data from controller to view in MVC?

Here Mudassar Ahmed Khan has explained with an example, how to use the JsonResult class object for returning JSON data from Controller to View in ASP.Net MVC. The Controller Action method will be called using jQuery POST function and JSON data will be returned back to the View using JsonResult class object.


2 Answers

Using JSON.NET you can call SerializeObject to "flatten" the expando object:

dynamic expando = new ExpandoObject(); expando.name = "John Smith"; expando.age = 30;  var json = JsonConvert.SerializeObject(expando); 

Will output:

{"name":"John Smith","age":30} 

In the context of an ASP.NET MVC Controller, the result can be returned using the Content-method:

public class JsonController : Controller {     public ActionResult Data()     {         dynamic expando = new ExpandoObject();         expando.name = "John Smith";         expando.age = 30;          var json = JsonConvert.SerializeObject(expando);          return Content(json, "application/json");     } } 
like image 160
Mikael Koskinen Avatar answered Oct 27 '22 11:10

Mikael Koskinen


You could also, make a special JSONConverter that works only for ExpandoObject and then register it in an instance of JavaScriptSerializer. This way you could serialize arrays of expando,combinations of expando objects and ... until you find another kind of object that is not getting serialized correctly("the way u want"), then you make another Converter, or add another type to this one. Hope this helps.

using System.Web.Script.Serialization;     public class ExpandoJSONConverter : JavaScriptConverter {     public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)     {         throw new NotImplementedException();     }     public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)     {                  var result = new Dictionary<string, object>();         var dictionary = obj as IDictionary<string, object>;         foreach (var item in dictionary)             result.Add(item.Key, item.Value);         return result;     }     public override IEnumerable<Type> SupportedTypes     {         get          {                return new ReadOnlyCollection<Type>(new Type[] { typeof(System.Dynamic.ExpandoObject) });         }     } } 

Using converter

var serializer = new JavaScriptSerializer();  serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJSONConverter()}); var json = serializer.Serialize(obj); 
like image 35
Pablo Rodda Donate Avatar answered Oct 27 '22 13:10

Pablo Rodda Donate