将嵌套的json对象反序列化为c#对象

时间:2017-10-04 09:22:00

标签: c# json

我有以下Json回复:

JsonConvert.DeserializeObject<List<RootObject>>(s).Select(x => new {x.display_name, x.plugin_output, x.Host})

我为每位客户提供以下课程:

{
  "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"
    },
  ]
}

从这里我使用Json.Net和我的一个方法(摘录)中的以下代码,其中下面的客户是响应:

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; }
}

除了Address和Passport之外,CustomerDto中的所有值都被填充,这些值为null,我无法弄清楚原因。

3 个答案:

答案 0 :(得分:5)

您可以创建一个包含客户列表的类:

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

要反序列化对象,只需调用:

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

编辑: 没有注意到Customer是json数组中对象列表的嵌套属性,因此需要另一个包装CustomerDto的类。 @mwwills发布了完整的答案。

答案 1 :(得分:5)

添加两个新类:

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

答案 2 :(得分:2)

AddressDtoPassportDto不会被反序列化,只是因为您在JSON图中的某个级别进行反序列化。

写一个类:

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

然后在for循环中反序列化:

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

现在,您将看到所有内容都按预期填充。