Преобразование массива JSON в объект класса

У меня есть JSON ниже, и я пытаюсь преобразовать его в класс Utilities.

Я добавил класс Root для облегчения взаимодействия массива JSON в список класса Utilities. Я получаю объектный объект, возвращаемый каждым из методов, которые я пробовал, но все поля пусты. Каков правильный подход?

JSON содержится в записях (0).

[{"jobid":"BKTD3G4YOY","planned":"2018-10-16T16:07:28.9963532+00:00","routedate":"2018-10-16T17:07:28.0000000+01:00","estimated":"2018-10-16T17:07:28.0000000+01:00","notification":true,"ID":"3eb41e22-9f68-457e-851b-a97b00e98f6d","loss":23,"breakTimeLoss":0,"information":"Tour Create/Update"},{"jobid":"KP8W1XJVZ8","planned":"2018-10-16T18:07:28.9963532+00:00","routedate":"2018-10-16T19:48:45.0000000+01:00","estimated":"2018-10-16T19:48:45.0000000+01:00","notification":true,"ID":"3eb41e22-9f68-457e-851b-a97b00e98f6d","loss":23,"breakTimeLoss":0,"information":"Tour Create/Update"}]

<DataContract()> 
Public Class Utilities
    <DataMember()>
    Public Property jobid As String
        Get
            Return m_scmid
        End Get
        Set(value As String)
            m_scmid = value
        End Set
    End Property
    Private m_scmid As String
    <DataMember()>
    Public Property planned As DateTime
        Get
            Return m_planned
        End Get
        Set(value As DateTime)
            m_planned = value
        End Set
    End Property
    Private m_planned As DateTime
    <DataMember()>
    Public Property routedate As DateTime
        Get
            Return m_routedate
        End Get
        Set(value As DateTime)
            m_routedate = value
        End Set
    End Property
    Private m_routedate As DateTime
    <DataMember()>
    Public Property estimated As DateTime
        Get
            Return m_estmated
        End Get
        Set(value As DateTime)
            m_estmated = value
        End Set
    End Property
    Private m_estmated As DateTime
    <DataMember()>
    Public Property notification As Boolean
        Get
            Return m_notification
        End Get
        Set(value As Boolean)
            m_notification = value
        End Set
    End Property
    Private m_notification As Boolean
    <DataMember()>
    Public Property ID As String
        Get
            Return m_ID
        End Get
        Set(value As String)
            m_ID = value
        End Set
    End Property
    Private m_ID As String
    <DataMember()>
    Public Property source As source
        Get
            Return m_source
        End Get
        Set(value As source)
            m_source = value
        End Set
    End Property
    Private m_source As source
    <DataMember()>
    Public Property loss As Integer
        Get
            Return m_loss
        End Get
        Set(value As Integer)
            m_loss = value
        End Set
    End Property
    Private m_loss As Integer
    Private m_breakTimeLoss As Integer
    <DataMember()>
    Public Property information As String
        Get
            Return m_information
        End Get
        Set(value As String)
            m_information = value
        End Set
    End Property
    Private m_information As String 
End Class 

<DataContract()> 
Public Class source
    <DataMember()>
    Public Property timeStamp As DateTime
        Get
            Return m_timeStamp
        End Get
        Set(value As DateTime)
            m_timeStamp = value
        End Set
    End Property
    Private m_timeStamp As DateTime
    <DataMember()>
    Public Property direction As Integer
        Get
            Return m_direction
        End Get
        Set(value As Integer)
            m_direction = value
        End Set
    End Property
    Private m_direction As Integer 
End Class 

<DataContract()> 
Public Class Root
    <DataMember()>
    Public Property entry As List(Of Utilities)
        Get
            Return m_entry
        End Get
        Set(value As List(Of Utilities))
            m_entry = value
        End Set
    End Property
    Private m_entry As List(Of Utilities) 
End Class

Попытка первого метода:

 Dim serializer = New DataContractJsonSerializer(GetType(List(Of Root)))
 Dim ms As MemoryStream = New MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(entries(0)))
 Dim obj As List(Of Root) = CType(serializer.ReadObject(ms), List(Of Root))

И второй метод попытался:

 Dim account As List(Of Root) = JsonConvert.DeserializeObject(Of List(Of Root))(entries(0))

Спасибо за ответы, после того, как вчера я разместил этот вопрос, мне удалось заставить мой код работать. Однако мне пришлось добавить настройки для обработки дат смещения в json!

Dim jsonSerializerSettings = New JsonSerializerSettings
                jsonSerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat
                jsonSerializerSettings.DateParseHandling = DateParseHandling.DateTimeOffset
                jsonSerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind

                Dim obj = JsonConvert.DeserializeObject(Of Root)(entries(0), jsonSerializerSettings)                                              

Выглядит правильно. Похоже, проблема в entries(0). Вы отлаживали и проверяли фактическое содержимое записей (0) во время выполнения? Кроме того, попробуйте установить точки останова в установщиках и посмотрите, не сработают ли они во время десериализации.

user1228 22.10.2018 16:00

Привет, да, единственное, что, как мне кажется, может вызывать проблему, - это то, что некоторые даты являются значениями смещения как «2018-10-16T19: 48: 45.0000000 + 01: 00», следует ли мне изменить членов класса, чтобы отразить это?

joebohen 22.10.2018 16:03

Изменил DateTime на DateTimeOffset, но данные по-прежнему не загружаются!

joebohen 22.10.2018 16:12
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
3
111
2

Ответы 2

Добавленный вами класс Root вызывает здесь проблему, потому что элементы массива в вашем JSON не имеют этого дополнительного слоя (в них нет свойства с именем entry). На самом деле вам вообще не нужен этот класс-оболочка. Вам нужно просто десериализовать прямо в List(Of Utilities).

Dim list As List(Of Utilities) = JsonConvert.DeserializeObject(Of List(Of Utilities))(entries(0))

Кроме того, вы можете упростить свой класс Utilities, используя Автореализуемые свойства. Это избавит вас от необходимости объявлять резервные поля и писать методы Get и Set для каждого свойства. Кроме того, если вы собираетесь использовать Json.Net вместо DataContractJsonSerializer, вам не нужны здесь атрибуты DataContract и DataMember. Однако Json.Net будет их уважать.

Еще одна вещь: я заметил, что в вашем классе отсутствует общедоступное свойство для breakTimeLoss, которое присутствует в JSON, поэтому вам нужно будет добавить его, если вы хотите зафиксировать это значение. И наоборот, ваш класс имеет свойство Source, для которого нет соответствующей информации в JSON. Это нормально - это не вызовет ошибок или чего-то еще, но просто хотел упомянуть, что это кажется ненужным.

Со всеми этими изменениями объявление класса будет выглядеть так:

Public Class Utilities
    Public Property jobid As String
    Public Property planned As DateTime
    Public Property routedate As DateTime
    Public Property estimated As DateTime
    Public Property notification As Boolean
    Public Property ID as String
    Public Property loss As Integer
    Public Property breakTimeLoss As Integer
    Public Property information As String
End Class

Рабочая рабочий пример: https://dotnetfiddle.net/bfSsts

Спасибо за ответы, после того, как вчера я разместил этот вопрос, мне удалось заставить мой код работать. Однако мне пришлось добавить настройки для обработки дат смещения в json!

joebohen 23.10.2018 11:03

Привет, ниже представлена ​​иерархия вашего класса.

   Public Class Utilities

        <JsonProperty("jobid")>
        Public Property Jobid As String

        <JsonProperty("planned")>
        Public Property Planned As DateTime

        <JsonProperty("routedate")>
        Public Property Routedate As DateTime

        <JsonProperty("estimated")>
        Public Property Estimated As DateTime

        <JsonProperty("notification")>
        Public Property Notification As Boolean

        <JsonProperty("ID")>
        Public Property ID As String

        <JsonProperty("loss")>
        Public Property Loss As Integer

        <JsonProperty("breakTimeLoss")>
        Public Property BreakTimeLoss As Integer

        <JsonProperty("information")>
        Public Property Information As String
   End Class

Другие вопросы по теме