简体   繁体   English

复杂的 Json 到 C# Object 用类反序列化

[英]Complicated Json to C# Object Deserialize with classes

I am trying to deserialize a json response I get from a web call.我正在尝试反序列化从 web 调用中获得的 json 响应。 I have it 90 percent figured out.我有 90% 想通了。 The only part I am having a hard time figuring out is there are these json arrays which have data in them and each array name is unique using the email address.我很难弄清楚的唯一部分是这些 json arrays 其中包含数据,并且每个数组名称使用 email 地址是唯一的。 I have not been able to figure out how to turn the Email Arrays into 1. Dynamic and having it create many lists or just a couple depending on what comes back in the response and also dynamically naming the list arrays to put the data into the Records class.我无法弄清楚如何将 Email Arrays 转换为 1. 动态并让它创建许多列表或仅创建几个列表,具体取决于响应中返回的内容,并且还动态地将列表 ZA3CBC3F9D0CE2F2C1554E1B671D71 命名为 RecordsD71 class。

As you can see in the Records class I need this to be more dynamic and flexible to receive any and all emails.正如您在记录 class 中看到的那样,我需要它更加动态和灵活地接收任何和所有电子邮件。

Below is the json:下面是 json:

{
  "result": {
    "records": {
      "joeblow@gmail.com": [
        {
          "OrderId": "d9535109-d305-4584-a503-8194bbcfcff2",
          "CompletedOrderId": "BCFCFF2",
          "CustomerId": 1212,
          "CompletedTime": "2020-10-26 13:32:02",
          "Email": "joeblow@gmail.com",
          "ShippingFirstName": "Joe",
          "ShippingMiddleName": "",
          "ShippingLastName": "Blow",
          "LineItems": {
            "tfl.es.bluray": { "qty": 1 },
            "booklets.en.ebook": { "qty": 1 }
          }
        }
      ],
      "cleob@hotmail.com": [
        {
          "OrderId": "7bf97b3a-bc46-411c-bc30-12563326dba0",
          "CompletedOrderId": "326DBA0",
          "CustomerId": 1212,
          "CompletedTime": "2020-10-26 20:07:44",
          "Email": "cleob@hotmail.com",
          "ShippingFirstName": "Cleo",
          "ShippingMiddleName": "",
          "ShippingLastName": "Blue",
          "LineItems": {
            "tfl.es.bluray": { "qty": 1 },
            "booklets.en.ebook": { "qty": 1 },
            "aos.en.pb": { "qty": 1 },
            "course-tos.en.olr": { "qty": 1 },
            "pow-hsk-nofilm.en.combo": { "qty": 1 },
            "course-organizing.en.olr": { "qty": 1 }
          }
        }
      ],
      "johnd@gmail.com": [
        {
          "OrderId": "630f0dda-94c3-4b82-a070-2554004dce29",
          "CompletedOrderId": "04DCE29",
          "CustomerId": 12345,
          "CompletedTime": "2020-10-25 21:52:04",
          "Email": "johnd@gmail.com",
          "ShippingFirstName": "John",
          "ShippingMiddleName": "",
          "ShippingLastName": "Doe",
          "LineItems": {
            "tfl.es.bluray": { "qty": 1 },
            "booklets.en.ebook": { "qty": 1 },
            "aos.en.pb": { "qty": 1 },
            "course-tos.en.olr": { "qty": 1 },
            "pow-hsk-nofilm.en.combo": { "qty": 1 },
            "course-organizing.en.olr": { "qty": 1 },
            "oak-2007.en.cd": { "qty": 1 }
          }
        }
      ]
    },
    "errors": [
      {
        "id": "bademailaddress-yahoo.com",
        "message": "Email address 'bademailaddress-yahoo.com' is not a valid email address"
      }
    ]
  },
  "jsonrpc": "2.0",
  "id": 12345634523
} 

And the classes I made for the json deserialization:我为 json 反序列化创建的类:

public partial class JsonEmailDeSerializer
{
    [JsonProperty("result")]
    public Result Result { get; set; }

    [JsonProperty("jsonrpc")]
    public string Jsonrpc { get; set; }

    [JsonProperty("id")]
    public long Id { get; set; }
}

public partial class Result
{
    [JsonProperty("records")]
    public Records Records { get; set; }

    [JsonProperty("errors")]
    public List<Error> Errors { get; set; }
}

public partial class Error
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }
}

public partial class Records
{
    [JsonProperty("joeblow@gmail.com")]
    public List<MailCom> JoeblowGmailCom { get; set; }

    [JsonProperty("cleob@hotmail.com")]
    public List<MailCom> CleobHotmailCom { get; set; }

    [JsonProperty("johnd@gmail.com")]
    public List<MailCom> JohndGmailCom { get; set; }
}

public partial class MailCom
{
    [JsonProperty("OrderId")]
    public Guid OrderId { get; set; }

    [JsonProperty("CompletedOrderId")]
    public string CompletedOrderId { get; set; }

    [JsonProperty("CustomerId")]
    public long CustomerId { get; set; }

    [JsonProperty("CompletedTime")]
    public DateTimeOffset CompletedTime { get; set; }

    [JsonProperty("Email")]
    public string Email { get; set; }

    [JsonProperty("ShippingFirstName")]
    public string ShippingFirstName { get; set; }

    [JsonProperty("ShippingMiddleName")]
    public string ShippingMiddleName { get; set; }

    [JsonProperty("ShippingLastName")]
    public string ShippingLastName { get; set; }

    [JsonProperty("LineItems")]
    public Dictionary<string, LineItem> LineItems { get; set; }
}

public partial class LineItem
{
    [JsonProperty("qty")]
    public long Qty { get; set; }
}

public partial class JsonEmailDeSerializer
{
    public static JsonEmailDeSerializer FromJson(string json) => JsonConvert.DeserializeObject<JsonEmailDeSerializer>(json, FedExShipper.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this JsonEmailDeSerializer self) => JsonConvert.SerializeObject(self, FedExShipper.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters =
        {
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

You can use Dictionary<string, List<MailCom>> for records property:您可以将Dictionary<string, List<MailCom>>用于记录属性:

public partial class Result
{
    [JsonProperty("records")]
    public Dictionary<string, List<MailCom>> Records { get; set; }

    [JsonProperty("errors")]
    public List<Error> Errors { get; set; }
}

Json.NET can treat json object properties as keys for dictionary which makes it suitable to deserialize such dynamic data. Json.NET 可以将 json object 属性视为字典的键,这使得它适合反序列化此类动态数据。

That will never serialize to a class properly.那永远不会正确地序列化为 class 。

You'll have to use a lower-level API like Utf8JsonReader to read that level in the document, at least.至少,您必须使用较低级别的 API (例如Utf8JsonReader)来读取文档中的该级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM