#c# #json #json.net
#c# #json #json.net
Вопрос:
Я пытаюсь десериализовать ответ json, который я получаю от веб-вызова. Я понял это на 90 процентов. Единственная часть, которую мне трудно понять, — это то, что есть эти массивы json, в которых есть данные, и каждое имя массива уникально с использованием адреса электронной почты. Я не смог понять, как превратить массивы электронной почты в 1. Динамический и позволяющий создавать множество списков или всего пару в зависимости от того, что возвращается в ответе, а также динамически присваивать имена массивам списков для помещения данных в класс Records.
Как вы можете видеть в классе Records, мне нужно, чтобы это было более динамичным и гибким для получения любых электронных писем.
Ниже приведен 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
}
И классы, которые я создал для десериализации 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 }
},
};
}
Комментарии:
1. Итак, я знаю, что ваш язык, который вам нужен, — это C #, но если у вас есть или вы используете Visual Studio code, вы можете установить конвертер JSON в Typescript, который может преобразовывать строку JSON в эквивалентный класс TS. Я знаю, что это не C #, но TS легко переводится на него. Вот популярный вариант, который вы можете найти в VS marketplace . marketplace.visualstudio.com /…
Ответ №1:
Общий подход к десериализации json с динамическими именами свойств заключается в использовании Dictionary<string, ...>
, в данном случае — Dictionary<string, List<MailCom>>
может использоваться для Records
свойства:
public partial class Result
{
[JsonProperty("records")]
public Dictionary<string, List<MailCom>> Records { get; set; }
[JsonProperty("errors")]
public List<Error> Errors { get; set; }
}
Json.NET может обрабатывать свойства объекта json как ключи для словаря, что делает его пригодным для десериализации таких динамических данных. То же самое верно для System.Text.Json
.
Ответ №2:
Это никогда не будет сериализовано в класс должным образом.
Вам придется использовать API более низкого уровня, например Utf8JsonReader, по крайней мере, для чтения этого уровня в документе.