首页 > 解决方案 > 如何从 VB.Net 中的另一个 JSON 对象创建新的 JSON 对象?

问题描述

我在 VB.Net 中使用以下代码来获取一组 JSON 格式的时间和温度数据,我将最终绘制图表。我想转换 JSON 数据,但我只能创建 jObject。在那之后,我迷路了。我承认,我有点新手!

Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

Partial Class public_html_JSON
    Inherits System.Web.UI.Page
    Public jResults As JObject
    Public rawresp As String
    Public strStartTime As String = ""
    Public strEndTime As String = ""
    Public rangeMinutes As Long
    Public debugText As String


    Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load

    Dim request As HttpWebRequest
    Dim response As HttpWebResponse = Nothing
    Dim reader As StreamReader
    Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
    Dim cstTime As DateTime = TimeZoneInfo.ConvertTimeFromUtc(DateAdd(DateInterval.Day, 0, DateAdd(DateInterval.Hour, 0, Now().ToUniversalTime)), cstZone)request =        

    Dim url As String = "https://[somesite]?method=queryList4Chart&device.id=17002&endTime=" + strEndTime + "&sensorNumber=-1&startTime=" + strStartTime
    request = DirectCast(WebRequest.Create(url), HttpWebRequest)
    response = DirectCast(request.GetResponse(), HttpWebResponse)
    reader = New StreamReader(response.GetResponseStream())
    rawresp = reader.ReadToEnd()
    response = Nothing

    jResults = JObject.Parse(rawresp)

但在我将它发送到客户端之前,我想:

  1. 使用“x, y”格式创建一个新的 JSON 字符串,timeArray 为“x”,dataArray[0] 为“y”。
  2. 通过仅保持可被 5 整除的分钟数来减少数据点的数量。(即 5、10、15 等...)

这是我要转换的数据:

   "dataArray":[ 
      [ 
         { 
            "value":13.4
         },
         { 
            "value":13.2
         },
         { 
            "value":13.2
         },
         { 
            "value":13.5
         }
      ],
      [ 
         { 
            "value":2.8
         },
         { 
            "value":2.8
         },
         { 
            "value":2.9
         },
         { 
            "value":3.0
         }
      ]
   ],
   "sensorArray":[ 
      "1.TP1(℃)",
      "2.TP2(℃)"
   ],
   "timeArray":[ 
      "2019/11/10 14:00:41",
      "2019/11/10 14:05:40",
      "2019/11/10 14:07:40",
      "2019/11/10 14:10:40"
   ]
}

我需要这种格式:

[ 
   { 
      "x":2019/11/10 14:00:00,
      "y":13.4
   },
   { 
      "x":2019/11/10 14:05:00,
      "y":13.2
   },
   { 
      "x":2019/11/10 14:10:00,
      "y":13.5
   }
]

我该怎么做呢?

标签: jsonvb.netlinq

解决方案


感谢 Craig 的建议,这是最终的工作代码!

Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json

Partial Class KFPTempsV2
    Inherits System.Web.UI.Page
    Public strStartTime As String = ""
    Public strEndTime As String = ""
    Public rangeMinutes As Long
    Public debugText As String
    Public JSONxy As ArrayList = New ArrayList 'List of JSON strings

    Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load

        Dim request As HttpWebRequest
        Dim response As HttpWebResponse = Nothing
        Dim reader As StreamReader
        Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
        Dim cstTime As DateTime = TimeZoneInfo.ConvertTimeFromUtc(DateAdd(DateInterval.Day, 0, DateAdd(DateInterval.Hour, 0, Now().ToUniversalTime)), cstZone)
        Dim DeviceList As IEnumerable(Of TemperatureDevice) = GetTemperatureDevices()
        Dim rawResp As String
        Dim url As String = ""
        Dim objXY As New List(Of List(Of XY))

        rangeMinutes = 1440
        strStartTime = DateAdd(DateInterval.Minute, -rangeMinutes, cstTime).ToString("MM/dd/yyyy\%20HH:mm:00")
        strEndTime = cstTime.ToString("MM/dd/yyyy\%20HH:mm:ss")

        'Get data from each device
        For Each dv As TemperatureDevice In DeviceList
            url = "https://www.[somesite].com/deviceDataAction.do?method=queryList4Chart&device.id=" & dv.ID & "&endTime=" + strEndTime + "&sensorNumber=-1&startTime=" + strStartTime
            request = DirectCast(WebRequest.Create(url), HttpWebRequest)
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            reader = New StreamReader(response.GetResponseStream())
            rawResp = reader.ReadToEnd()
            response = Nothing

            Dim XYList As List(Of XY) = ConvertToXY(JsonConvert.DeserializeObject(Of JSONData)(rawResp))

            JSONxy.Add(JsonConvert.SerializeObject(XYList))
            objXY.Add(XYList) 'Store XYList for later use
        Next

        'Populate Current/H/L temperatures
        Current1.InnerHtml = objXY(0)(objXY(0).Count - 1).y
        High1.InnerHtml = MaxValue(objXY(0)).ToString
        Low1.InnerHtml = MinValue(objXY(0)).ToString

        Current2.InnerHtml = objXY(1)(objXY(1).Count - 1).y
        High2.InnerHtml = MaxValue(objXY(1)).ToString
        Low2.InnerHtml = MinValue(objXY(1)).ToString

        Current3.InnerHtml = objXY(2)(objXY(2).Count - 1).y
        High3.InnerHtml = MaxValue(objXY(2)).ToString
        Low3.InnerHtml = MinValue(objXY(2)).ToString

        Current4.InnerHtml = objXY(3)(objXY(3).Count - 1).y
        High4.InnerHtml = MaxValue(objXY(2)).ToString
        Low4.InnerHtml = MinValue(objXY(3)).ToString

    End Sub

    Function ConvertToXY(obj As JSONData) As List(Of XY)

        Dim NewObj As List(Of XY) = New List(Of XY)

        For i As Int16 = 0 To obj.DataArray(1).Length - 1
            Dim oDate As DateTime = Convert.ToDateTime(obj.TimeArray(i))
            Dim oNewDate As DateTime = New DateTime(oDate.Year, oDate.Month, oDate.Day, oDate.Hour, oDate.Minute, 0).AddMinutes(Math.Round(oDate.Second / 60))
            If oNewDate.Minute Mod 5 = 0 Then
                Dim objXY As XY = New XY
                objXY.x = oNewDate.ToString("yyyy/MM/dd HH:mm:ss")
                objXY.y = obj.DataArray(1)(i).Value
                NewObj.Add(objXY)
            End If
        Next

        Return NewObj

    End Function

    Function MinValue(oList As List(Of XY)) As String

        Dim sglMin As Single = 200

        For Each row As XY In oList
            Try
                If CSng(row.y) < sglMin Then
                    sglMin = CSng(row.y)
                End If
            Catch ex As Exception

            End Try
        Next

        Return sglMin.ToString("F1")

    End Function

    Function MaxValue(oList As List(Of XY)) As String

        Dim sglMax As Single = -200

        For Each row As XY In oList
            Try
                If CSng(row.y) > sglMax Then
                    sglMax = CSng(row.y)
                End If
            Catch ex As Exception

            End Try
        Next

        Return sglMax.ToString("F1")

    End Function

    Public Class JSONData

        Public Property DataArray As DataArray()()
        Public Property SensorArray As String()
        Public Property TimeArray As String()

    End Class

    Public Class DataArray

        Public Property Value As String

    End Class

    Class XY 'Important that xy field names be lowercase

        Property x As String
        Property y As String

    End Class

    Public Class TemperatureDevice

        Public Name As String
        Public ID As String
        Public DatasetNum As Int16

        Public Sub New()
        End Sub

        Public Sub New(ByVal _name As String,
                       ByVal _id As String,
                       ByVal _datasetNum As Int16
                       )
            Name = _name
            ID = _id
            DatasetNum = _datasetNum
        End Sub

    End Class

    Private Function GetTemperatureDevices() As IEnumerable(Of TemperatureDevice)

        'Dataset choices TP1=0 Or TP2=1
        Return New List(Of TemperatureDevice) From
            {
             New TemperatureDevice("Pump House", "17002", 1),
             New TemperatureDevice("Planer", "7199", 1),
             New TemperatureDevice("Sawmill", "7123", 1),
             New TemperatureDevice("Wellons", "13293", 1)
             }

    End Function

End Class

推荐阅读