【问题标题】:Deserialization problem with DataContractJsonSerializerDataContractJsonSerializer 的反序列化问题
【发布时间】:2010-10-10 10:09:50
【问题描述】:

我有以下 JSON:

[{
    "name": "numToRetrieve",
    "value": "3",
    "label": "Number of items to retrieve:",
    "items": {
        "1": "1",
        "3": "3",
        "5": "5"
    },
    "rules": {
        "range": "1-2"
    }
},
{
    "name": "showFoo",
    "value": "on",
    "label": "Show foo?"
},
{
    "name": "title",
    "value": "Foo",
    "label": "Foo:"
}]

多合一版本(适用于字符串文字):

[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}]

在上面的示例中,namevaluelabel 是必需的,但 itemsrules 是可选的。

这是我要反序列化的类:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace foofoo
{
    [DataContract]
    public sealed class FooDef
    {
        [DataMember(Name = "name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "value", IsRequired = true)]
        public string Value { get; set; }

        [DataMember(Name = "label", IsRequired = true)]
        public string Label { get; set; }

        [DataMember(Name = "items", IsRequired = false)]
        public Dictionary<string, string> Items { get; set; }

        [DataMember(Name = "rules", IsRequired = false)]
        public Dictionary<string, string> Rules { get; set; }
    }
}

这是我用来反序列化的代码:

var json = new DataContractJsonSerializer(typeof(List<FooDef>));
var bar = "[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}]";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(bar));
var foo = json.ReadObject(stream);
stream.Close();

除了itemsrules 第一次FooDef 传递为空之外,一切都进行得相当顺利。我已经在阳光下尝试了所有方法来尝试填充它们:自定义类、NameValueCollectionKeyValuePair&lt;string, string&gt;List 两者,以及似乎适用的所有其他集合。 [编辑:我忘了尝试Hashtable,这似乎是一个明显的候选人。没用。]

在我看来,问题在于itemsrules 下的关键部分是开放式的。也就是说,它并不总是被称为range3。有什么建议或想法吗?

【问题讨论】:

    标签: c# wcf json dictionary serialization


    【解决方案1】:

    恕我直言,无法使用 DataContractJsonSerializer 将您提供的 JSON 字符串反序列化为 .NET 类。

    问题来自DataContractJsonSerializer 序列化字典的方式。您可以使用替代序列化程序,例如Json.NET(我强烈推荐)或JavaScriptSerializer(我认为它已被弃用,取而代之的是 DataContractJsonSerializer,但它适用于您的场景)。

    您也可以阅读theserants

    文档:Serializing Collections - Json.NET

    【讨论】:

    • 这就是我所担心的。由于弃用,我避免切换到 JavaScriptSerializer,但我很高兴听到它在 3.5 SP1 中未被弃用。我会尝试使用该类。
    • 我用 JavaScriptSerializer 试了一下,效果很好。我最终使用了 Dictionary 但 Hashtable 也可以使用。
    【解决方案2】:

    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/071f73bb-e141-4a68-ae61-05635382934f

    查看这篇文章 - 它几乎完美地解决了我的问题。我不得不将他们的 object[] 类型更改为字符串,但我只使用字符串:字符串类型的键/值对,所以那里没有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多