从太阳能逆变器 API 反序列化 JSON

Deserialise JSON from a solar inverter API

我有 JSON 来自 Fronius 太阳能逆变器的数据。我正在尝试将其读入 VB.NET classes,这样我就可以对它进行一些其他操作(添加到数据库、使用信息来控制家用设备等)。 我已经通过一些在线资源解析了JSON,都说没问题。
当 运行 我的代码时 classes 什么都没有回来。
这是反序列化的基本代码:

Dim fileReader As System.IO.StreamReader = My.Computer.FileSystem.OpenTextFileReader("C:\Temp\JsonCrap.js")
Dim jsonData As String = fileReader.ReadToEnd
fileReader.Close()
Dim myJs = JsonConvert.DeserializeObject(Of Body)(jsonData)

当我展开 myJS 时,它显示了我的 class 中的数据属性,但没有任何值。
JSON是这样的:

{
   "Body" : {
      "Data" : {
         "DAY_PMAX" : {
            "Unit" : "W",
            "Value" : 2013
         },
         "DAY_UACMAX" : {
            "Unit" : "V",
            "Value" : 244.80000000000001
         },
         "DAY_UDCMAX" : {
            "Unit" : "V",
            "Value" : 375.19999999999999
         },
         "TOTAL_PMAX" : {
            "Unit" : "W",
            "Value" : 5568
         },
         "TOTAL_UACMAX" : {
            "Unit" : "V",
            "Value" : 285.5
         },
         "TOTAL_UDCMAX" : {
            "Unit" : "V",
            "Value" : 389.19999999999999
         },
         "YEAR_PMAX" : {
            "Unit" : "W",
            "Value" : 5562
         },
         "YEAR_UACMAX" : {
            "Unit" : "V",
            "Value" : 277.30000000000001
         },
         "YEAR_UDCMAX" : {
            "Unit" : "V",
            "Value" : 375.19999999999999
         }
      }
   },
   "Head" : {
      "RequestArguments" : {
         "DataCollection" : "MinMaxInverterData",
         "DeviceClass" : "Inverter",
         "DeviceId" : "1",
         "Scope" : "Device"
      },
      "Status" : {
         "Code" : 0,
         "Reason" : "",
         "UserMessage" : ""
      },
      "Timestamp" : "2021-07-22T11:34:44+10:00"
   }
}

并且 classes 在这里:

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization

Public Class Body
    <JsonProperty(PropertyName:="Body")>
    Public Property Data As Data
End Class

Public Class Data
    <JsonProperty(PropertyName:="DAY_PMAX")>
    Public Property DAY_PMAX As DAYPMAX

    <JsonProperty(PropertyName:="DAY_UACMAX")>
    Public Property DAY_UACMAX As DAYUACMAX

    <JsonProperty(PropertyName:="DAY_UDCMAX")>
    Public Property DAY_UDCMAX As DAYUDCMAX

    <JsonProperty(PropertyName:="TOTAL_PMAX")>
    Public Property TOTAL_PMAX As TOTALPMAX

    <JsonProperty(PropertyName:="TOTAL_UACMAX")>
    Public Property TOTAL_UACMAX As TOTALUACMAX

    <JsonProperty(PropertyName:="TOTAL_UDCMAX")>
    Public Property TOTAL_UDCMAX As TOTALUDCMAX

    <JsonProperty(PropertyName:="YEAR_PMAX")>
    Public Property YEAR_PMAX As YEARPMAX

    <JsonProperty(PropertyName:="YEAR_UACMAX")>
    Public Property YEAR_UACMAX As YEARUACMAX

    <JsonProperty(PropertyName:="YEAR_UDCMAX")>
    Public Property YEAR_UDCMAX As YEARUDCMAX
End Class

Public Class DAYPMAX
    Public Property Unit As String
    Public Property Value As Integer
End Class

Public Class DAYUACMAX
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class DAYUDCMAX
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class TOTALPMAX
    Public Property Unit As String
    Public Property Value As Integer
End Class

Public Class TOTALUACMAX
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class TOTALUDCMAX
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class YEARPMAX
    Public Property Unit As String
    Public Property Value As Integer
End Class

Public Class YEARUACMAX
    Public Property Unit As String
    Public Property Value As Double
End Class



Public Class YEARUDCMAX
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class RequestArguments
    Public Property DataCollection As String
    Public Property DeviceClass As String
    Public Property DeviceId As String
    Public Property Scope As String
End Class

Public Class Status
    Public Property Code As Integer
    Public Property Reason As String
    Public Property UserMessage As String
End Class

Public Class Head
    Public Property RequestArguments As RequestArguments
    Public Property Status As Status
    Public Property Timestamp As DateTime
End Class

Public Class Example
    Public Property Body As Body
    Public Property Head As Head
End Class

您的 class 模型缺少 Root 对象。如果简化JSON结构就可以看到:BodyHead包含在一个Object中(因此,两者都是同一个Root对象的属性)。

{
   "Body" : {
},
   "Head" : {
   }
}

添加一个包含这些属性的 Root 对象:

Public Class FroniusAPIRoot
    Public Property Body As Body
    Public Property Head As Head
End Class

我建议简化模型:Data class 的所有属性只是一个对象类型,JSON 对象 属性 名称是关键获取相关对象。
您可以简单地使用 Dictionary(Of String, Class) 来处理 Data.
的所有属性 它也更灵活,以防这些属性可以更改或者 API 可以 return more/different 对象,具体取决于查询的类型。

Partial Public Class Body
    Public Property Data As Dictionary(Of String, UnitValues)
End Class

Public Class UnitValues
    Public Property Unit As String
    Public Property Value As Double
End Class

使用 FroniusAPIRoot class 反序列化你的 JSON:

Dim json = File.ReadAllText("C:\Temp\JsonCrap.js")
Dim froniusData = JsonConvert.DeserializeObject(Of FroniusAPIRoot)(json)

修改后的class型号:
注意:我不确定 RequestArguments.DeviceId 应该被解释为字符串还是整数值。它在 JSON 中被定义为字符串。根据需要修改(整数、长整型)。

如果您不喜欢字典,请加回数据 class 及其所有属性,但使用 UnitValues class 来定义类型(因为都可以使用相同的类型)。

Public Class FroniusAPIRoot
    Public Property Body As Body
    Public Property Head As Head
End Class

Public Class Body
    Public Property Data As Dictionary(Of String, UnitValues)
End Class

Public Class UnitValues
    Public Property Unit As String
    Public Property Value As Double
End Class

Public Class Head
    Public Property RequestArguments As RequestArguments
    Public Property Status As Status
    Public Property Timestamp As DateTimeOffset
End Class

Public Class RequestArguments
    Public Property DataCollection As String
    Public Property DeviceClass As String
    Public Property DeviceId As String
    Public Property Scope As String
End Class

Public Class Status
    Public Property Code As Long
    Public Property Reason As String
    Public Property UserMessage As String
End Class