2017-10-04 140 views
3

我有以下JSON響應:反序列化嵌套的JSON對象爲C#對象

{ 
    "Customers": [ 
    { 
     "Customer": { 
     "Address": { 
      "City": "Stockholm", 
      "PostalCode": "10123" 
     }, 
     "Classifications": [ 
      "LoyaltyProgram", 
      "Returning", 
      "VeryImportant" 
     ], 
     "FirstName": "Peter", 
     "LastName": "Centers", 
     "Passport": { 
      "Expiration": "2019-01-14", 
      "Number": "1564931321655" 
     }, 
     }, 
     "FirstName": "Peter", 
     "LastName": "Centers", 
     "Reservation": { 
     "AdultCount": 2, 
     "AssignedSpaceId": "03f59360-8644-4e29-927a-ad85a6514466", 
     }, 
     "RoomNumber": "302" 
    }, 
    ] 
} 

我必須爲每一位客戶下列類:

public class CustomerDto 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public List<string> Classifications { get; set; } 
    public PassportDto Passport { get; set; } 
    public AddressDto Address { get; set; } 
} 

public class AddressDto 
{ 
    public string City { get; set; } 
    public string PostalCode { get; set; } 
} 

public class PassportDto 
{ 
    public string Expiration { get; set; } 
    public string Number { get; set; } 
} 
從這個我用Json.Net和

以下代碼從我的一個方法(提取)其中客戶以下是響應:

var jsonCustomers = JObject.Parse(customers)["Customers"].Children().ToList(); 
IList<CustomerDto> customerList = new List<CustomerDto>(); 
foreach (var item in jsonCustomers) { 
    customerList.Add(item.ToObject<CustomerDto>()); 
} 

Custome中的所有值除地址和護照之外,rDto都是空白的,我無法弄清楚原因。

回答

4

添加兩個新類:

public class CustomersWrapper 
{ 
    public IEnumerable<CustomerWrapper> Customers { get; set; } 
} 

public class CustomerWrapper 
{ 
    public CustomerDto Customer { get; set; } 
} 

,然後用替換所有現有代碼:

 var results = JsonConvert.DeserializeObject<CustomersWrapper>(input); 
     var customerList = results.Customers.Select(z => z.Customer).ToList(); 

這將確保標準deserialisation出現在層次結構中的所有對象。

由於您的JSON結構奇怪,因此這是必需的。 https://stackoverflow.com/a/45384366/34092是相同的基本問題(可能值得一讀) - 基本上你不應該在你的JSON中有CustomersCustomer。沒有這些,你就不需要我指定的兩個包裝類。

您也可能希望避免在JSON中指定FirstNameLastName兩次(不必要)。

+0

是的,我沒有照顧FirstName和LastName的外部值,只是得到「客戶」。 –

+0

是的,它工作得很完美,謝謝。 :) Json響應來自另一個來源/公司(在線酒店預訂系統),我無法控制代碼。我同意Json的迴應看起來有點奇怪,當被問到它時,他們說這是因爲後向兼容性。 –

4

您可以創建具有客戶上有一個列表類:

public class CustomerList 
{ 
    public IList<CustomerDto> Customers { get; set; } 
} 

而反序列化對象只要致電:

CustomerList jsonCustomers = JsonConvert.DeserializeObject<CustomerList>(customers); 
IList<CustomerDto> customerList = jsonCustomers.Customers; 

編輯: 沒有注意到客戶是json數組中的對象列表中的嵌套屬性,所以需要另一個類包裝CustomerDto。 @mjwills發佈了完整的答案。

+0

這是一個很好的代碼示例,但不能解決問題。添加此代碼,仍然會將Address和Pasport設置爲Nothing(空)。 – Moim

+0

是的,只是意識到我錯過了json的結構,@mjwills用正確的答案更新了他們的答案。 –

2

AddressDtoPassportDto將不會被反序列化,只是因爲您在JSON圖中的某個級別反序列化。

寫一個類,如:

public class WrapCustomer 
{ 
     public CustomerDto Customer { get; set; } 
} 

然後反序列化這個在您的for循環:

customerList.Add(item.ToObject<WrapCustomer>()); 

現在你會看到你希望的一切都被填充。