#json #vb.net #json.net
#json #vb.net #json.net
Вопрос:
У меня есть rest API, который возвращает мне ответ json, представляющий собой массив документов, который, в свою очередь, имеет несколько массивов сам по себе. Ниже приведен пример документа, который я хотел бы десериализовать
{
"DocId": "contact::6f128681-218d-409d-b71d-31031852057d",
"Name": "Joe F Miller",
"buckets": [
{
"DocId": "leadbucket::5652A756-5B58-45A5-9566-9C85E8783440",
"text": "Dead Leads"
},
{
"DocId": "leadbucket::8A234FC1-6389-485D-8BDE-7FCB1E7639E0",
"text": "No Follow-Up Needed"
},
{
"DocId": "leadbucket::C97632BE-5A24-4AE7-8D18-4DFE174F0D0F",
"text": "Long-Term Buyers"
},
{
"DocId": "leadbucket::D6802064-8AC5-4E5A-855E-B59C32859C81",
"text": "New Lead"
}
],
"emails": [
{
"other": "demo@test.com"
},
{
"work": "work@demo.com"
},
{
"work": "work2@demo.com"
}
],
"followup": {
"date": "05/01/2019",
"type": "phone"
},
"lastactivity": "04/05/2019",
"phones": [
{
"home": "(213) 444-2222"
},
{
"work": "(949) 555-1212"
}
],
"tags": [
{
"DocId": "tag::FC276FBD-DC3A-4E18-8244-E89EF24E022E",
"text": "Buyer"
},
{
"DocId": "tag::EA5DE0FB-34B0-4F7C-B631-177D6BD2F65E",
"text": "Investor"
}
]
}
После того, как я получу ответ от моего API, я использую приведенный ниже код, чтобы попытаться преобразовать данные.
ContactList = JsonConvert.DeserializeObject(Of List(Of Contact.ContactList))(read.Item("Data").ToString)
Итак, я надеюсь, что кто-нибудь сможет указать мне правильное направление в том, как создать класс для хранения документов такого типа и как его десериализовать. Должен ли я делать это в своем классе или мне нужно вызывать десериализацию для каждого массива в Json?
Еще одна проблема, с которой я сталкиваюсь, — это раздел электронных писем и телефонов, поскольку значение ключа не уникально, и я не всегда знаю, что будет возвращено. как бы я создал класс для хранения этого, поскольку ключевое поле может измениться.
Комментарии:
1. Попробуйте json2csharp.com , он сгенерирует правильную структуру классов для десериализации JSON в
2. Как и где я мог бы реализовать IEnumerable(словаря (строки, String)) ? я бы предположил, что я бы поместил его в класс, который определяет данные для этого. Я смог определить сегменты и теги, которые я создал в своем классе, в виде списка (тегов)
Ответ №1:
Пример, использование IEnumerable(Of Dictionary(Of String, String))
для десериализации объектов JSON, которые имеют неопределенное количество элементов, с неопределенной комбинацией пар (ключ, значение) для каждого объекта.
Ключевая часть также может повторяться, как показано в примере:
"emails": [
{"other": "demo@test.com"},
{"work": "work@demo.com"},
{"work": "work2@demo.com"}
other
, work
Ключи могут отличаться каждый раз и могут повторяться.
Десериализация / сериализация этого свойства с помощью IEnumerable(Of Dictionary(Of String, String))
, позволяет
Пример объекта класса Contacts содержит методы (упрощенные здесь), которые выполняют десериализацию объекта JSON и сериализацию корня объекта, воспроизводя исходный объект JSON.
Эти методы являются статическими (совместно используемыми), вам просто нужно вызвать метод, нет необходимости создавать экземпляр класса Contacts.
Например, десериализовать объект JSON (строку, полученную от службы):
Dim myContacts As Contacts.RootObject = Contacts.DeserializeJSON(JSONObject)
Сериализуйте объект класса обратно в исходную строку:
Dim myJsonContacts = Contacts.SerializeJSON(myContacts)
Сравните только что сериализованный JSON с оригиналом и посмотрите, совпадают ли они.
Перечислите все электронные письма и номера телефонов в десериализованном объекте класса:
(просто пример: преобразование в список не требуется)
myContacts.Emails.ToList().ForEach(
Sub(em) Console.WriteLine($"from: {em.Keys(0)}, Email: {em.Values(0)}"))
myContacts.Phones.ToList().ForEach(
Sub(ph) Console.WriteLine($"place: {ph.Keys(0)}, Phone Number: {ph.Values(0)}"))
Доступ к одному электронному письму (или номеру телефона):
(конечно, можно использовать любой другой метод извлечения (Key, Value)
пары из словаря)
Dim eMailFrom = myContacts.Emails(0).Keys(0)
Dim eMailValue = myContacts.Emails(0).Values(0)
Получите все электронные письма из определенного места ( work
, здесь):
Dim emailFromWork = myContacts.Emails.Where(Function(em) em.Keys.Contains("work"))
Contacts
Класс:
Некоторые свойства украшены <JsonProperty()>
. Имя свойства изменено, потому что исходный JSON использует имена, которые являются зарезервированными ключевыми словами в языке.
Например:
<JsonProperty("text")>
Public Property BucketText As String
Imports Newtonsoft.Json
Public Class Contacts
Public Shared Function DeserializeJSON(JsonObject As String) As RootObject
Return JsonConvert.DeserializeObject(Of RootObject)(JsonObject)
End Function
Public Shared Function SerializeJSON(classObject As RootObject) As String
Return JsonConvert.SerializeObject(classObject)
End Function
Partial Public Class RootObject
Public Property DocId As String
Public Property Name As String
Public Property Buckets As List(Of Bucket)
Public Property Emails As Dictionary(Of String, String)()
Public Property Followup As Followup
Public Property Lastactivity As String
Public Property Phones As IEnumerable(Of Dictionary(Of String, String))
Public Property Tags As List(Of Tag)
End Class
Partial Public Class Bucket
Public Property DocId As String
<JsonProperty("text")>
Public Property BucketText As String
End Class
Partial Public Class Tag
Public Property DocId As String
<JsonProperty("text")>
Public Property TagText As String
End Class
Partial Public Class Followup
<JsonProperty("date")>
Public Property FollowupDate As String
<JsonProperty("type")>
Public Property FollowupType As String
End Class
End Class