如何在ASP.NET MVC中通过JsonResult返回的ExpandoObject对象进行扁平化处理?

100

我很喜欢在运行时编译服务器端动态对象时使用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中筛选“Key”、“Value”,但我希望在向客户端发送数据之前就解决这个问题。感谢您的帮助!


10
为何不直接使用Dictionary<string, object>而使用ExpandoObject呢?因为它能自动序列化成你想要的格式,而且你只是像使用字典一样使用ExpandoObject。如果你想要序列化合法的ExpandoObject,那么使用"return new JsonResult(d.ToDictionary(x => x.Key, x => x.Value));"方法可能是最好的折衷方案。 - BrainSlugs83
12个回答

-2

我刚遇到了同样的问题,发现了一些相当奇怪的东西。 如果我这样做:

dynamic x = new ExpandoObject();
x.Prop1 = "xxx";
x.Prop2 = "yyy";
return Json
(
    new
    {
        x.Prop1,
        x.Prop2
    }
);

它可以工作,但只有当我的方法使用HttpPost属性时。如果我使用HttpGet,我会得到错误。 因此,我的答案仅适用于HttpPost。在我的情况下,这是一个Ajax调用,所以我可以将HttpGet更改为HttpPost。


2
-1 这并不是真正有用的,因为它归结为 https://dev59.com/-Gw05IYBdhLWcg3wxUj_#7042631,并且如果你要在静态地依赖于名称的情况下动态地执行这些操作,那么做这些事情就没有意义。AllowGet问题完全是无关的。 - Ruben Bartelink

-2

看起来序列化器将Expando转换为字典,然后进行序列化(因此出现了键/值的情况)。您是否尝试过将其反序列化为字典,然后将其转换回Expando?


1
Expando对象实现了IDictionary<string, object>,所以我认为这就是为什么JsonResult将其序列化为键/值对数组的原因。将其强制转换为IDictionary再转回来并不能真正帮助它变平,恐怕是这样的。 - TimDog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接