2013-06-20 127 views
3

在SO上可能有500个这样的问题,并且有100万个网站提供所有信息 - 但我无法看到树木。这似乎应该是令人尴尬的简单做法,但我无法使其工作。JSON反序列化绝望(无法反序列化嵌套类型)

我有一个WCF Web服务,它返回一个序列化JSON对象:

[OperationContract(Name = "PeopleData"), WebGet(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "people/{subset}", ResponseFormat = WebMessageFormat.Json)] 
PeopleObject GetPeople(string subset); 

这工作 - 如果我打的URI从一个浏览器,GetPeople被调用和返回节录的JSON序列化PeopleObject(实际数据值隐私在这里):

{"HashValue":"XXXXX","People":[{"EmailAddress":"XXXXX","EmployeeID":99999,"Gender":"X","JobTitle":"XXXXX","Office":"","PreferredName":"XXXXX","Surname":"XXXXX","WorkExtensionNumber":"XXXXX","WorkPhoneNumber":"XXXXX","Department":"XXXXX","DeskNumber":"XXXXX","EmploymentClassification":"XXXXX","InternationalExtensionNumber":"XXXXX","IsFirstAider":false,"Languages":[{"LanguageID":9,"LanguageSkillID":9},{"LanguageID":9,"LanguageSkillID":9}],"QualificationInitials":"XXXXX","QualificationTitle":"XXXXX","Secretaries":null,"WorkMobilePhoneNumber":"XXXXX"}],"RecordCount":"1","SizeBytes":"12345"} 

在这个例子中PeopleObject有效载荷包含集合中只有一个Person对象,但可能包含许多(取决于/{subset}提供的参数。

这里是类层次结构PeopleObject - 这是一个顶层容器持股约净荷一些元数据,并Person对象的名单<>。到目前为止,一切都很好

[DataContract] 
    public class PeopleObject 
    { 
    [DataMember] 
    public string HashValue { get; set; } 
    [DataMember] 
    public List<Person> People { get; set; } 
    [DataMember] 
    public string RecordCount { get; set; } 
    [DataMember] 
    public string SizeBytes { get; set; } 
    } 

    [DataContract] 
    public class Person 
    { 
    [DataMember] 
    public string EmailAddress { get; set; } 
    // <-- snip - lots of fields like this, no point listing them all here 
    [DataMember] 
    public bool IsFirstAider { get; set; } 
    [DataMember] 
    public List<Language> Languages { get; set; } 
    [DataMember] 
    public List<Secretary> Secretaries { get; set; } 
    } 

    [DataContract] 
    public class Language 
    { 
    [DataMember] 
    public int LanguageID { get; set; } 
    [DataMember] 
    public int LanguageSkillID { get; set; } 
    } 

    [DataContract] 
    public class Secretary 
    { 
    [DataMember] 
    public int EmployeeID { get; set; } 
    [DataMember] 
    public char FirstSurnameLetter { get; set; } 
    } 

- WCF与回应:这些对象反过来有一堆简单类型的属性,加上Language另外两个嵌套表<>和Secretary对象(这可能会或可能不会进行填充)一个包含所有字段及其内容的JSON结构。现在反序列化客户端应用程序的结构(使用相同的类层次结构定义):

// I have a little helper-class to manage the WCF request and return a Stream 
    using (Stream response = wcfHelper.GetRequestResponseStream(MY_WCF_URI)) 
    { 
    // This is debug code to prove the response arrives as expected - it does 
    //StreamReader sr = new StreamReader(response); 
    //Console.WriteLine("\nResponse:\n{0}", sr.ReadToEnd()); 

    // Deserialise the response 
    DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(PeopleObject)); 
    PeopleObject p = (PeopleObject)dc.ReadObject(response); 

    // The object shows 1 record (in the example) but nothing in the List<> 
    Console.WriteLine("\nDeserialized records: '{0}' [{1}]", p.RecordCount, p.People.Count); 
    } 

所以这个正确的反序列化容器对象,给我以字节为单位的记录数,散列值,有效载荷大小。该对象也具有Person对象的列表,但它为空 - 来自JSON响应的内容未通过创建和添加Person对象成功地重新水化列表<>。

我错过了什么?我的理解是,从JSON结构中再次合并C#对象层次结构应该会自动发生,所以要么不是这种情况(我需要编写一些代码来实现它)或者是,但是我错过了一些明显的东西。

+1

在黑暗中刺戳:“枚举类型可以用DataContractAttribute属性标记,在这种情况下,参与序列化的每个成员都必须用EnumMemberAttribute属性标记。未标记的成员不会被序列化。 http://msdn.microsoft.com/en-us/library/ms731923.aspx – jbabey

+0

@jbabey我认为这是指'enum'类型,而不是像'List ' –

+1

http://msdn.microsoft.com /en-us/library/bb908209.aspx你还需要给它一个所有子类型的列表。 – crush

回答

1

我没有做过,你之前在做什么,而是由documentation来看,我认为以下将工作:

List<Type> types = new List<Type>(); 
types.Add(typeof(Person)); 
types.Add(typeof(Language)); 
types.Add(typeof(Secretary)); 

DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(PeopleObject), types); 
PeopleObject p = (PeopleObject)dc.ReadObject(response); 

你基本上需要告诉串行所有可能遇到的类型同时序列化/反序列化你的对象。

+0

的儿子... 是的。搞定了。你摇滚。 –