How to Flatten an Expandoobject Returned via JSONresult in ASP.NET MVC

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

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

JsonResult from an already jsoned string

I managed to get it working with a sort of trick, but I'd like to know if there is a better solution for this, and at any rate if it is true that I really need to use JsonResult (or a derived class, like in this trick) to get JS work properly. I derived a class from JsonResult and changed the ExecuteResult method so that it just passes through the received JSON string:

public sealed class PassthroughJsonResult : JsonResult
{
public string Json { get; set; }

public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");

HttpResponseBase response = context.HttpContext.Response;

if (!String.IsNullOrEmpty(ContentType))
response.ContentType = ContentType;
else
response.ContentType = "application/json";

if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;

if (Json != null) response.Write(Json);
}
}

How do I give a name to my ExpandoObject while serialize process?

You can try using Dictionary<string, ExpandoObject> instead of List<ExpandoObject>:

var categoryList = new Dictionary<string, ExpandoObject>>();
for (int i = 0; i < mainForm.categories.Count; i++)
{
ExpandoObject z = new ExpandoObject();
(z as IDictionary<string, object>)["name"] = mainForm.categories[i].CategoryName;
(z as IDictionary<string, object>)["prop1"] = HexConverter(mainForm.categories[i].prop1);
(z as IDictionary<string, object>)["prop2"] = HexConverter(mainForm.categories[i].prop2);
(z as IDictionary<string, object>)["prop3"] = HexConverter(mainForm.categories[i].prop3);
(z as IDictionary<string, object>)["prop4"] = HexConverter(mainForm.categories[i].prop4);
categoryList["someName" + i] = z;
}

Also I would say that you can use Dictionary<string, object> instead of ExpandoObject for z.

How do I make WebMethods serialize ExpandoObject

It sounds like you've already figured this out, but here's something I threw together a while back to do just that:

public class ExpandoObjectConverter : JavaScriptConverter {
public override IEnumerable<Type> SupportedTypes {
get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(ExpandoObject) })); }
}

public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
ExpandoObject expando = (ExpandoObject)obj;

if (expando != null) {
// Create the representation.
Dictionary<string, object> result = new Dictionary<string, object>();

foreach (KeyValuePair<string, object> item in expando) {
if (item.Value.GetType() == typeof(DateTime))
result.Add(item.Key, ((DateTime)item.Value).ToShortDateString());
else
result.Add(item.Key, item.Value.ToString());
}

return result;
}
return new Dictionary<string, object>();
}

public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
return null;
}
}

Then, you just need to add it to the <converters> section in your web.config, as shown in the MSDN article you linked to:

<configuration>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="ExpandoObjectConverter" type="ExpandoObjectConverter"/>
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
</configuration>


Related Topics



Leave a reply



Submit