簡體   English   中英

將嵌套的 json 對象反序列化為 c# 對象

[英]Deserialize nested json objects into c# objects

我有以下 Json 響應:

{
  "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>());
}

CustomerDto 中的所有值都被填充,除了 Address 和 Passport,它們都是空的,我不知道為什么。

添加兩個新類:

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();

這將確保對層次結構中的所有對象進行標准反序列化。

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

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

您可以創建一個包含客戶列表的類:

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

而反序列化對象只需調用:

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

編輯:沒有注意到 Customer 是 json 數組中對象列表上的嵌套屬性,因此需要另一個包裝CustomerDto類。 @mjwills 已經發布了完整的答案。

AddressDtoPassportDto不會被反序列化,因為您正在 JSON 圖中的上一級反序列化。

寫一個類,如:

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

然后在你的 for 循環中反序列化它:

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

現在您將看到一切都按您的預期填充。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM