2009-02-27 154 views
22

我有JSON的下面片:与DataContractJsonSerializer反序列化问题

[{ 
    "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<string, string>List这两个后者,以及其他所有似乎适用的集合。 [编辑:我忘了尝试Hashtable,这似乎是一个明显的候选人。没有工作。]

问题,因为我认为它是itemsrules下的关键部分是开放式的。也就是说,它并不总是被称为range3。任何建议或想法?

回答

21

恕我直言,没有办法反序列化您使用DataContractJsonSerializer提供给.NET类的JSON字符串。

问题来自于序列化字典的方式DataContractJsonSerializer。你可以使用另一个序列化器,比如Json.NET(我强烈推荐)或者JavaScriptSerializer(我认为它已经被弃用,用于DataContractJsonSerializer,但它适用于你的场景)。您也可以阅读theserants

文档:Serializing Collections - Json.NET

+0

这是我所担心的。由于反对,我避免切换到JavaScriptSerializer,但我很高兴听到它在3.5 SP1中不赞成。我会用这个班级来尝试。 – bbrown 2009-03-02 03:48:20