序列化ExpandoObject与ServiceStack.Text序列化、ExpandoObject、Text、ServiceStack

由网友(偏执)分享简介:我想序列化与图书馆 ServiceStack.Text 的对象。这适用I am trying to serialize objects with the library ServiceStack.Text . This works using System.Dynamic;using ServiceStack.T...

我想序列化与图书馆 ServiceStack.Text 的对象。这适用

I am trying to serialize objects with the library ServiceStack.Text . This works

using System.Dynamic;
using ServiceStack.Text;
var x = new {Value= 10, Product = "Apples"};                
Console.WriteLine(JsonSerializer.SerializeToString(x));

我得到的,因为我希望

I get, as I expect

{"Value":10,"Product":"Apples"}

然而

dynamic x = new ExpandoObject();
x.Value = 100;
x.Product = "Apples";
Console.WriteLine(JsonSerializer.SerializeToString(x));

我得到我吃惊的是

I get to my surprise

[{"Key":"Value","Value":100},{"Key":"Product","Value":"Apples"}]

为什么!这是怎么回事?

Why! What's going on?

第二,我怎么能得到我想要什么?的

推荐答案

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&LT; KeyValuePair&GT; ,和所以它系列化,以键/值对的JSON数组。

My guess is that internally, the ServiceStack serializer is treating the ExpandoObject as an IEnumerable<KeyValuePair>, and so it serializes to a JSON array of key/value pairs.

这不同于你的第一个(工作)code段,因为.NET实际上建立了一个真正的(匿名)类为您的数据,基本上它使:

This differs from your first (working) code snippet because .NET actually builds a real (anonymous) class for your data, basically it makes:

public class SomeNameTheCompilerMakesUp {
    internal int Value { get; set; }
    internal string Product { get; set; }
}

自动为您,所以当它被发送到串行化器,它正在与一个真正的类不动产,而 ExpandoObject 真的是由 [对象] 内部。

在一个侧面说明,微软 System.Web.Helpers.Json 进行同样的操作。该测试通过:

On a side-note, Microsoft's System.Web.Helpers.Json behaves the same way. This test passes:

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

最后一个编辑:的

One final edit:

您可以使这项工作要通过旋转的方式你的 ExpandoObject 词典&LT;字符串,对象&gt; 。需要说明的这个code是它复制数据到一本字典,让你有2份内存(或略小于,由于技术上的弦可能会扣留)。

You can make this work the way you want by turning your ExpandoObject into a Dictionary<string, object>. The caveat to this code is that it duplicates the data into a dictionary, so you have 2 copies in memory (or slightly less than, since technically the strings might be interned).

    [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 是这样的:

Although, for anyone that comes across this later, and is actually using System.Web.Helpers.Json, the better thing to do is just wrap your ExpandoObject in a DynamicJsonObject like this:

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

答一次,我通过努力,我发现了一个类似的问题在这里:How扁平化的ExpandoObject通过JsonResult在asp.net mvc的返回?

阅读全文

相关推荐

最新文章