ExpandoObject
实施IConnection<KeyValuePair>
and IEnumerable<KeyValuePair>
:
public sealed class ExpandoObject :
IDynamicMetaObjectProvider,
IDictionary<string, object>,
ICollection<KeyValuePair<string, object>>,
IEnumerable<KeyValuePair<string, object>>,
IEnumerable, INotifyPropertyChanged
我的猜测是,ServiceStack 序列化器在内部正在处理ExpandoObject
as an IEnumerable<KeyValuePair>
,因此它序列化为键/值对的 JSON 数组。
这与您的第一个(工作)代码片段不同,因为 .NET 实际上为您的数据构建了一个真实的(匿名)类,基本上它使:
public class SomeNameTheCompilerMakesUp {
internal int Value { get; set; }
internal string Product { get; set; }
}
自动为您服务,因此当它被发送到序列化器时,它正在使用具有真实属性的真实类,而ExpandoObject
确实得到了支持object[]
内部。
顺便说一句,微软的System.Web.Helpers.Json
行为方式相同。该测试通过:
[TestMethod]
public void ExpandoObjectSerializesToJsonArray()
{
dynamic anonType = new { Value = 10, Product = "Apples" };
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
var anonResult = System.Web.Helpers.Json.Encode(anonType);
var expandoResult = System.Web.Helpers.Json.Encode(expando);
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", anonResult);
Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult);
}
最后一次编辑:
您可以通过转动您的ExpandoObject
into a Dictionary<string, object>
。这段代码需要注意的是,它将数据复制到字典中,因此内存中有 2 个副本(或略少,因为从技术上讲,字符串可能会被保留)。
[TestMethod]
public void TestMethod1()
{
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
// copy expando properties to dictionary
var dictionary = ((ExpandoObject)expando).ToDictionary(x => x.Key, x => x.Value);
var expandoResult = System.Web.Helpers.Json.Encode(expando);
var dictionaryResult = System.Web.Helpers.Json.Encode(dictionary);
Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult);
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult);
}
不过,对于后来遇到这个问题并实际使用的人来说System.Web.Helpers.Json
,更好的办法就是把你的ExpandoObject
in a DynamicJsonObject
像这样:
[TestMethod]
public void TestMethod1()
{
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
var dictionaryResult = System.Web.Helpers.Json.Encode(new DynamicJsonObject(expando));
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult);
}
回答一旦我解决了这个问题,我在这里发现了一个类似的问题:如何在 asp.net mvc 中展平通过 JsonResult 返回的 ExpandoObject? https://stackoverflow.com/questions/5156664/how-to-flatten-an-expandoobject-returned-via-jsonresult-in-asp-net-mvc