Handling Json Array in VB.net - json

I am getting data from some monitoring equipment which is returning what I believe is a Json (nested) array but the syntax is not quite right.
Below is a sample of what is being retuned. Its an array of UnixTimeMilliseconds and a value.
[[1579617389000,132],[1579617399000,136],[1579617409000,139],[1579617419000,137]]
It could be up to 3000 sets of these numbers.
What I would like to do is dump them into an object of some sort an array so I am able to work with it e.g. translate the UnixTimeMilliseconds into datetime and do calculations.
Last thing I tried was:
Dim ListResultsArray As Directory()
ListResultsArray = JsonConvert.DeserializeObject(Of Directory())(emoncmsResponse)
and the error returned was:
Could not create an instance of type System.IO.Directory. Type is an interface or abstract class and cannot be instantiated. Path '[0].id', line 1, position 7.

A simple method to convert the Arrays is to parse the JSON with JArray, iterate the inner arrays and produce a new class object, converting the array values to the desired type.
Create an object that can represent the array values:
<JsonArray>
Public Class NumbersItem
Public Sub New(objTime As DateTimeOffset, objValue As Long)
DetectionTime = objTime
Value = objValue
End Sub
Public ReadOnly Property DetectionTime As DateTimeOffset
Public ReadOnly Property Value As Long
End Class
Then parse the JSON and generate new class objects from each inner JArray object:
Since the first value in the Array represent an Unix DateTime expressed in milliseconds, we can use the DateTimeOffset.FromUnixTimeMilliseconds() method to convert it.
Dim numbers As New List(Of NumbersItem)()
Dim jsonArrays = JArray.Parse(json)
For Each array As JArray In jsonArrays.Children()
numbers.Add(New NumbersItem(
DateTimeOffset.FromUnixTimeMilliseconds(CType(array.First, Long)),
CType(array.Last, Long)))
Next
Now, you can inspect each NumbersItem class object in the list as usual.
The DetectionTime property is defined as a DateTimeOffset because the Unix time is expressed in UTC coordinates. You can use the DateTimeOffset methods to determine the local DateTime (DateTimeOffset.ToLocalTime) or perform other conversions.

Have you tried JObject using NewtonSoft.json.Linq
Just create a JObject Array and parse Json
Dim object As JObject()
JObject.parse(object(index))

Related

Deserializing JSON into a List (or other object type)

I am having issues deserializing some JSON into an object type that I can work with.
I have been playing around with multiple different ways to deserialize something, but I cannot get any of them to work. I am trying, currently, to use the Newtonsoft.Json deserializer.
Public Class ServerRecord
Inherits Record
<Newtonsoft.Json.JsonProperty("sys_class_name")>
Public Property sys_class_name As String
Get
End Get
Set(value As String)
End Set
End Property
<Newtonsoft.Json.JsonProperty("host_name")>
Public Property host_name As String
Get
End Get
Set(value As String)
End Set
End Property
<Newtonsoft.Json.JsonProperty("u_recovery_time_achievable")>
Public Property u_recovery_time_achievable As String
Get
End Get
Set(value As String)
End Set
End Property
End Class
Dim lstSNServersList As New List(Of ServerRecord)
Dim objServiceNowTableAPIClient As TableAPI.TableAPIClient(Of ServerRecord)
Dim objServiceNowRESTQueryResponse As RESTQueryResponse(Of ServerRecord)
objServiceNowTableAPIClient = New TableAPIClient(Of wServerRecord)(strServiceNowCMDBServersTableName, strServiceNowInstanceName, strServiceNowUser, strServiceNowPassword)
strServiceNowQuery = "sys_class_name=cmdb_ci_win_server^ORsys_class_name=cmdb_ci_linux_server"
objServiceNowRESTQueryResponse = objServiceNowTableAPIClient.GetByQuery(strServiceNowQuery)
'this much does work and it does return a result set
'this is my attempt to convert this response into a list of ServerRecords, but this does not work currently:
lstSNServersList = JsonConvert.DeserializeObject(Of List(Of ServerRecord))(objServiceNowRESTQueryResponse.RawJSON)
The objServiceNowRestQueryResponse.RawJSON string looks like this (though much longer):
{
"result":[
{
"sys_id":"00040665dbxxxxxx96191e",
"u_recovery_time_achievable":"720",
"sys_class_name":"cmdb_ci_linux_server",
"host_name":"rlserver001"
},
{
"sys_id":"00ec543d1xxxx66e4bcb6d",
"u_recovery_time_achievable":"4",
"sys_class_name":"cmdb_ci_linux_server",
"host_name":"plserver001"
},
{
"sys_id":"0105d975dbxxxxx8961998",
"u_recovery_time_achievable":"",
"sys_class_name":"cmdb_ci_linux_server",
"host_name":"tlserver001"
}
]
}
This is the error message I get when trying to run my code:
Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in
Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[CMDBReconciliation.CMDBReconciliation+ServiceNowServerRecord]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array (e.g.
[1,2,3]) or change the deserialized type so that it is a normal .NET
type (e.g. not a primitive type like integer, not a collection type
like an array or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.
Path 'result', line 1, position 10.
This will work. It just extracts the array part from the json string.
Dim start As Integer = objServiceNowRESTQueryResponse.IndexOf("[")
Dim last As Integer = objServiceNowRESTQueryResponse.LastIndexOf("]")
lstSNServersList = JsonConvert.DeserializeObject(Of List(Of ServerRecord))(objServiceNowRESTQueryResponse.Substring(start, last - start + 1))

Deserializing Json VB.NET

I am trying to deserialize data from a webserver for a game launcher.
The API docs provide me the data in json format, but I have been struggling to be able to read that data I am given and store it as a variable to use to log in a player. I have also tried a few other things but I am just stuck now. Normally a response from the server would like like this:
{"success":"true","gameserver":"gameserver-alpha.toontownrewritten.com","cookie":"deadbeefdeafbeef0x123"}
The code to deserialize the data:
Dim result() As TTRServerResponse = JsonConvert.DeserializeObject(Of TTRServerResponse())(responseFromServer)
Class with the variables I want to store
Public Class TTRServerResponse
Public Property success As String
Public Property eta As String
Public Property position As String
Public Property queueToken As String
Public Property cookie As String
End Class
Any ideas where I messed up or what I should do? Thanks, Ben.
EDIT: Finally figured it out, I needed to change my result to: Dim result As TTRServerResponse = JsonConvert.DeserializeObject(Of TTRServerResponse) (responseFromServer) I also was returning the data incorrectly to my other sub by returning just result. What I needed to do was return result.success. I now have a better understanding.
You are trying to deserialize the JSON into an array but in your example it is a single object.
So assuming
Dim responseFromServer As String
is equal to
{"success":"true","gameserver":"gameserver-alpha.toontownrewritten.com","cookie":"deadbeefdeafbeef0x123"}
Which, according to the documentation you linked to, is suppose to be a single object,
then you need to update your code to deserialize a single object as appose to an array
Dim result As TTRServerResponse = JsonConvert.DeserializeObject(Of TTRServerResponse)(responseFromServer)

Convert JSON object array value to string array in VB.NET without loop

I've a JSON object array like this
dim d as string="[{name:'alex',age:20,id:1},{name:'John',age:22,id:2},
{name:'Philip',age:26,id:3},{name:'Mathew',age:27,id:4},
{name:'James',age:30,id:5},{name:'Antony',age:20,id:6},
{name:'Kevin',age:10,id:7}]"
I parsed the JSON string array using JSON serializer as this way.
DIM mj() as mysample
dim js as new javascriptserializer
mj=js.deserialize(Of mysample)(d)
But my requirement is to convert one attribute value of that json object to a string array based on a condition. For example the result array should contain all name with age 20.
The array should be ['Antony','Alex']
How can we achieve this without any loop. I mean some solution using LINQ
You can create a class with the properties found in you json, then use a library like newtonsoft to serielize your json to a list of object using your new class
public class Person{
public string name {get;set;}
public string age {get;set;}
}
List<Person> personList = JsonConvert.DeserializeObject<List<Person>>(jsonString);
Then use this list to run a linq to find the ones with age = 20
List<string> result = from personList.select(new {age = age}).where(p => p.age == 20)
This code is not tested just to provide a guide to the result.

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`

I know there's already a bunch of these questions on SO but none of those answers is working for me. I've been on it all day now and I'm just fried so it's an easy win for the JSON people out there.
The error is
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[FrozenSmoke.WorkflowDescription]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'Workflows', line 1, position 13.
The code is (VB.NET)
Dim z As New List(Of WorkflowDescription)
z = Newtonsoft.Json.JsonConvert.DeserializeObject(Of List(Of WorkflowDescription))(ResponseStatus.Content)
Here is the JSON I'm getting back from the server and is contained in ResponseStatus.Content
{"Workflows":[{"GUID":"594d2946-7bee-49b3-b8bf-e5ee6715a188","Name":"ProcessElectronicContribution"},{"GUID":"fe368a11-2b79-41f9-bee9-edb031612365","Name":"AddActivist"},{"GUID":"4c552492-0014-439d-952b-aeb320e6d218","Name":"AddPartialActivist"}]}
Here is the class
Public Class WorkflowDescription
Public Property Name As String = ""
Public Property GUID As String = ""
End Class
Your json is not simply an array/list but an object container which contains a Workflows property which is a list/array.
{"Workflows":[{"GUID": ....
Workflows is the List/Array but note that it is inside a brace. That is the "outer container".
Public Class WorkFlowContainer
Public Property WorkFlows As List(Of WorkflowItem)
End Class
Public Class WorkflowItem
Public Property Name As String
Public Property GUID As String
End Class
The WorkFlows element in the json will map to the property of the same name. You can get rid of the container after you deserialize:
' ultimate destination
Private myWorkFlows As List(Of WorkflowItem)
...
' elsewhere
Dim jstr = ... ` from whereever
' deserialize to the container
Dim wf = JsonConvert.DeserializeObject(Of WorkFlowContainer)(jstr)
' extract the list
myWorkFlows = wf.WorkFlows
You can ignore the WorkFlowContainer with an extra step in deseriazlizing:
Dim jstr = ... ` from whereever
Dim jopbj - JObject.Parse(jstr)
myWorkFlows = JsonConvert.DeserializeObject(Of List(Of WorkFlows))(jobj("Workflows"))
This way you dont have to define the extra class and dont have to use wf. to get at the data.
You probably know that most arrays can be deserialized as either a List or array. To define Workflows as a property array:
Public Property WorkFlows As WorkflowItem()

Deserialize JSON string into Dynamic List in VB.net

I've got the following JSON string which I have retrieved from a webapi:
[{"WorkOrderID":2,"WorkOrderNumber":1},{"WorkOrderID":3,"WorkOrderNumber":3}]
Now I want to know if there is a way I can deserialize this into a list of type dynamic in VB.NET?
The JSON string could be coming in any format (therefore I cannot deserialize it to a standard class type) and I just need to deserialize it into a list so it can be used a datasource for a grid.
Is this achievable.
For VB.Net:
Dim x As Object = JsonConvert.DeserializeObject(of Object)(json)