2013-06-20 128 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

的兒子... 是的。搞定了。你搖滾。 –