一尘不染

如何在ASP.NET MVC中展平通过JsonResult返回的ExpandoObject?

c#

我真的很喜欢在运行ExpandoObject时编译服务器端动态对象的过程,但是在JSON序列化过程中很难解决这个问题。首先,我实例化该对象:

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

到目前为止,一切都很好。在我的MVC控制器中,我想将其作为JsonResult发送下来,所以我这样做:

return new JsonResult(expando);

这会将JSON序列化为以下内容,供浏览器使用:

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

但是,我真正想要看到的是:

{SomeProp: SomeValueOrClass}

我知道,如果我使用dynamic而不是ExpandoObject-
JsonResult能够将dynamic属性和值序列化为单个对象(没有键或值业务),则可以实现此目的,
但是我需要使用的原因ExpandoObject是因为我不了解所有_据我所知, _直到运行时对象上需要的属性
,据我所知,如果dynamic不使用,就无法将属性动态添加到ExpandoObject

我可能必须在javascript中筛选“键”,“值”业务,但是我希望在将其发送给客户端之前先弄清楚这一点。谢谢你的帮助!


阅读 374

收藏
2020-05-19

共1个答案

一尘不染

您还可以制作一个仅适用于ExpandoObject的特殊JSONConverter,然后将其注册到JavaScriptSerializer的实例中。这样,您可以序列化expando的数组,expando对象的组合以及…,直到找到另一种未正确序列化的对象(“您想要的方式”),然后再制作一个Converter,或向其中添加其他类型这个。希望这可以帮助。

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

使用转换器

var serializer = new JavaScriptSerializer(); 
serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJSONConverter()});
var json = serializer.Serialize(obj);
2020-05-19