我试图序列与库对象ServiceStack.Text 。 这工作
using System.Dynamic;
using ServiceStack.Text;
var x = new {Value= 10, Product = "Apples"};
Console.WriteLine(JsonSerializer.SerializeToString(x));
我得到的,如我所料
{"Value":10,"Product":"Apples"}
然而
dynamic x = new ExpandoObject();
x.Value = 100;
x.Product = "Apples";
Console.WriteLine(JsonSerializer.SerializeToString(x));
我得到让我吃惊
[{"Key":"Value","Value":100},{"Key":"Product","Value":"Apples"}]
为什么! 这是怎么回事?
其次 , 我怎样才能得到我想要什么?
ExpandoObject
实现IConnection<KeyValuePair>
和IEnumerable<KeyValuePair>
:
public sealed class ExpandoObject :
IDynamicMetaObjectProvider,
IDictionary<string, object>,
ICollection<KeyValuePair<string, object>>,
IEnumerable<KeyValuePair<string, object>>,
IEnumerable, INotifyPropertyChanged
我的猜测是在内部,ServiceStack串行器处理ExpandoObject
作为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
到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
在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);
}
答一旦我通过努力,我发现了一个类似的问题在这里: 如何扁平化的ExpandoObject通过JsonResult在asp.net mvc的退换吗?