Convertion from array to json array isnt made properly using vb.net? - json

I am trying to convert an array into a json array. What I have is:
I have created a class where I declare the fields that I am going to use.
Public Class Response
Public container As Array
Public signature As Tuple(Of Object, String, Integer, String, Object, String)
Sub New()
Me.container = Nothing
Me.signature = Nothing
End Sub
Sub New(ByVal container As Array,
ByVal signature As Tuple(Of Object, String, Integer, String, Object, String))
Me.container = container
Me.signature = signature
End Sub
End Class
And the function where I want to convert them in JSON in order to use:
Public Function GetResponse()
Dim response As New Response
response.container = {"none", False}
response.signature = New Tuple(Of Object, String, Integer, String, Object, String)({10, 10},
"IT", 1, "Testing", {100, 100}, "Test Signature")
Dim JSONString As String = JsonConvert.SerializeObject(response)
Return JSONString
End Function
What I want it to look like is:
{ "container": {
"type": "none",
"single": false
},
"signature": {
"coordinates": {
"x": 10,
"y": 10
},
"location": "IT",
"page": 1,
"reason": "Testing",
"size": {
"height": 100,
"width": 100
},
"value": "Test Signature"
}
}
But what it looks like is:
{
"container": [
"none", false
],
"signature": {
"Item1": [10, 10],
"Item2": "IT",
"Item3": 1,
"Item4": "Testing",
"Item5": [100, 100],
"Item6": "Test Signature"
}
}
I am new to this, I would appriciate any help :) Thanks in advance!

That's the problem with using a Tuple; the properties don't have names you can choose. If you don't want to create a full on class for this data (and take a google for "Paste JSON as Classes"; there isn't much excuse for not having them), use an anonymous type:
Dim response = New With { _
.container = New With { .type = "none", .single = false }, _
.signature = New With { _
.coordinates = New With { .x = 10, .y = 10 }, _
.location = "IT", _
.someOtherName = someOtherValue, _
... etc ...
}

Related

Loop the contents of a JSON array object

I am new to Vb.net. Having a JSON string as given below, I tries to deserialize the JSON into an Object using JsonConvert.DeserializeObject().
I am trying to loop values inside the Content object in the given JSON to fetch its values.
I tried using a for loop, but I'm not able to get the exact values.
Dim result As String = {
"status": "0001",
"Result": {
"IsError": "0",
"Data": {
"Type": "a",
"Header": [
"v1",
"v2",
"v3",
"v4",
"v5"
],
"Content": [
[
"001",
"Raj",
"1",
"N",
""
],
[
"002",
"Vignesh",
"1",
"N",
""
],
[
"778",
"Ramesh",
"1",
"N",
""
],
[
"792",
"Suresh",
"1",
"N",
""
],
[
"703",
"Karthick",
"1",
"N",
""
],
[
"1247",
"Ram",
"1",
"N",
""
]
]
}
}
}
Dim jsonResult2 = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(result)
If you just want to deserialize the Content array, you can parse the JSON with JToken.Parse(), then deserialize to a List(Of String()) that section only.
Dim jsonResult = JToken.Parse(result)
Dim content = JsonConvert.DeserializeObject(Of List(Of String()))(
jsonResult("Result")("Data")("Content").ToString()
)
Or, you could use a class Model to deserialize the whole JSON, then access each object as a standard .Net Property value.
Public Class StatusResultsRoot
<JsonProperty("status")>
Public Property Status As String
Public Property Result As Result
End Class
Public Partial Class Result
Public Property IsError As String
Public Property Data As Data
End Class
Public Partial Class Data
<JsonProperty("Type")>
Public Property DataType As String
Public Property Header As List(Of String)
Public Property Content As List(Of String())
End Class
'[...]
Dim statusResult = JsonConvert.DeserializeObject(Of StatusResultsRoot)(result)
The Content List is then
Dim content As List(Of String()) = statusResult.Result.Data.Content
' Loop the List of String(), print the combined array of strings
For Each stringArray As String() In content
Console.WriteLine(String.Join(", ", stringArray))
Next
In case you actually want to embed a JSON as a string, you can use an XML element literal, defining an XElement by enclosing the JSON with <node> ... </node> markers.
You can then paste in the JSON as is (no need to double the double-quotes).
The JSON is then the string representation of the first node of the XElement: i.e., [XElement].FirstNode.ToString(). For example:
Dim xResult = <json> {
"status": "0001",
"Result": {
"IsError": "0",
"Data": {
' [... other content ...]
}
}
} </json>
Dim json As String = xResult.FirstNode.ToString()
You cannot do this in C#.
A string in VB must begin and end with a ".
The inner double quotes should be replaced with "".
So a proper string(when assigning it in code) would look like:
Dim result as string = "{
""status"": ""0001"",
...
}
"

Traversing Nested JSON using VBA

I have a JSON I am trying to parse in VBA. The JSON looks similar to the following:
{
"participantEligibilityResults": [
{
"eligibilityResult": {
"participantId": "HSA92a",
"clientId": "NIRCCCONFIG",
"environment": "CONFIG",
"errorReason": null,
"previousEvent": {
"eventDate": "2019-01-01",
"eventReason": "7",
"eligibilityDetails": [
{
"standardBenefitAreaId": "SPLIFE",
"benefitOptionId": "1XPay",
"coverageLevelId": "PPSP",
"employeeMonthlyCost": 216.67,
"employerMonthlyCost": 0.0,
"benefitProgramId": "ProgH"
},
{
"standardBenefitAreaId": "SPLIFE",
"benefitOptionId": "NoCoveragePay",
"coverageLevelId": null,
"employeeMonthlyCost": 0.0,
"employerMonthlyCost": 0.0,
"benefitProgramId": "ProgH"
}
],
"dependents": []
},
"currentEvent": {
"eventDate": "2020-03-14",
"eventReason": "5",
"eligibilityDetails": [
{
"standardBenefitAreaId": "BASICCHLIFE",
"benefitOptionId": "BCHWaive",
"coverageLevelId": null,
"employeeMonthlyCost": 0.0,
"employerMonthlyCost": 0.0,
"benefitProgramId": "ProgH",
"beneficiaryCollection": "Not Applicable",
"maxCoverageAmount": 0.0,
"minCoverageAmount": 0.0,
"coverageAmount": 0.0,
"preTax": true,
"postTax": false,
"userDefinedTaxability": false,
"numberOfPayPeriods": 52,
"payperiodsRemaining": 42.0
},
{
"standardBenefitAreaId": "DENTAL",
"benefitOptionId": "DentalPPO",
"coverageLevelId": "PPFAM2",
"employeeMonthlyCost": 29.17,
"employerMonthlyCost": 125.0,
"benefitProgramId": "ProgH",
"beneficiaryCollection": "Not Applicable",
"maxCoverageAmount": 0.0,
"minCoverageAmount": 0.0,
"preTax": true,
"postTax": false,
"userDefinedTaxability": false,
"numberOfPayPeriods": 52,
"payperiodsRemaining": 42.0
}
],
"dependents": [
{
"fullName": "Allison Drew ",
"dependentId": "5d82c4bf-609d-4c2f-8c1b-7d8fdd8b9fde",
"relationshipType": "Spouse",
"birthDate": "1980-01-01",
"activeIndicator": true,
"approvedIndicator": true,
"studentIndicator": false,
"coverages": [
{
"standardBenefitAreaId": "DENTAL",
"benefitOptionId": "NoCoverageDental",
"dependentCoverageRequired": false,
"activeCourtOrdered": false
},
{
"standardBenefitAreaId": "MEDICAL",
"benefitOptionId": "NoCoverageMedical",
"dependentCoverageRequired": false,
"activeCourtOrdered": false
}
]
},
{
"fullName": "Adam Drew ",
"dependentId": "d3f97b64-4a50-4dea-bec8-51d3db39352a",
"relationshipType": "Child",
"birthDate": "2012-01-01",
"activeIndicator": true,
"approvedIndicator": true,
"studentIndicator": false,
"coverages": [
{
"standardBenefitAreaId": "DENTAL",
"benefitOptionId": "NoCoverageDental",
"dependentCoverageRequired": false,
"activeCourtOrdered": false
},
{
"standardBenefitAreaId": "MEDICAL",
"benefitOptionId": "NoCoverageMedical",
"dependentCoverageRequired": false,
"activeCourtOrdered": false
}
]
}
]
}
},
"changes": []
}
]
}
I am currently utilizing VBA-JSON from https://github.com/VBA-tools/VBA-JSON to parse the JSON.
JsonOptions.AllowUnquotedKeys = True
Set JSON = JsonConverter.ParseJson(jsonResponse)
Ultimately, I am looking to access participantResults | eligibilityResult | currentEvent | eligibilityDetails and participantResults | eligibilityResult | currentEvent | dependents. I have tried beginning to traverse the JSON using something like:
For Each Eligibility In JSON("participantEligibilityResults")
For Each Detail In Eligibility("eligibilityResult")
'DO SOMETHING HERE
Next
Next
Unfortunately, once I parse at the participantEligibilityResults level, I am unable to access the levels below. I get an error "Object doesn't support this property or method." Can someone point me in the right direction?
Everything enclosed in {} will be output as a dictionary, everything enclosed in [] will be a collection. You just need to follow the nesting to get where you want.
Sub Test()
Dim result As String
Dim Item, a
Dim parsedResult As Object, obj, node, k
'loading from a cell for testing...
Set parsedResult = JsonConverter.ParseJson(Sheet2.Range("A1").Value)
Set obj = parsedResult("participantEligibilityResults")(1)("eligibilityResult")
Set node = obj("currentEvent")("eligibilityDetails")(1)
DumpJSon node 'see below
Set node = obj("currentEvent")("dependents")(1)
DumpJSon node 'see below
End Sub
If there are specific items you want, then trying to create nested loops to get to them will likely not be very useful - identify the paths you want and access the values directly. If you need to (eg) loop over a collection then that needs to be part of your approach.
It's sometimes useful to double-check what you have in your parsed result, so you can use this to dump it to the Immediate window (the whole thing or only parts of it)
Sub DumpJSon(obj, Optional level As Long = 0)
Const LEVEL_STEP As Long = 5
Dim k, v, n, s, tmp
If TypeName(obj) = "Dictionary" Then
For Each k In obj.keys
s = String(level, "-") & k & " = "
If IsObject(obj(k)) Then
Debug.Print s & IIf(obj(k).Count = 0, "Empty ", "") & _
TypeName(obj(k))
DumpJSon obj(k), level + LEVEL_STEP
Else
Debug.Print s & obj(k)
End If
Next k
ElseIf TypeName(obj) = "Collection" Then
n = 1
For Each v In obj
s = String(level, "-") & "(Item #" & n & ") "
If IsObject(v) Then
Debug.Print s & IIf(v.Count = 0, "Empty ", "") & _
TypeName(v)
DumpJSon v, level + LEVEL_STEP
Else
Debug.Print s & v
End If
n = n + 1
Next v
End If
End Sub

VBA: count items in JSON response string / trello get Cards count in a List

I'm using VBA-web (https://vba-tools.github.io/VBA-Web/) to access trello api, to get cards in a list
My function looks like that:
Public Function CountCardsinList(ListId As String) As Integer
WebHelpers.EnableLogging = False
Dim TrelloClient As New WebClient
TrelloClient.BaseUrl = "https://api.trello.com/1/"
Dim Request As New WebRequest
Request.Format = WebFormat.Json
Request.ResponseFormat = Json
Request.Resource = "lists/{ListId}/cards"
Request.AddUrlSegment "ListId", ListId
Request.AddQuerystringParam "key", TrelloAPIKey
Request.AddQuerystringParam "token", TrelloAPIToken
Request.AddQuerystringParam "filter", "open"
Dim Response As WebResponse
Set Response = TrelloClient.Execute(Request)
If Response.StatusCode = WebStatusCode.Ok Then
Debug.Print Response.Content '
'Response.Data("idList").Count
Debug.Print "CountCardsinList =>>> " & Response.Content
CountCardsinList = Response.Data("idList").Count
Else
MsgBox Response.StatusDescription, vbCritical, "Error " & Response.StatusCode
CountCardsinList = ""
End If
Debug.Print "CountCardsinList =>>> " & Response.Content
'Set CountCardsinList = Request
End Function
I receive correct JSON reply from the api:
[{
"id": "584e798dd570ae187b293e5b",
"checkItemStates": null,
"closed": false,
"dateLastActivity": "2016-12-30T09:24:57.531Z",
"desc": "",
"descData": null,
"idBoard": "57873ba94794058756fa0a96",
"idList": "57873bb3a725f734089702b2",
"idMembersVoted": [],
"idShort": 90,
"idAttachmentCover": null,
"manualCoverAttachment": false,
"idLabels": ["57873ba984e677fd3683bef8"],
"name": "card name / other stuff",
"pos": 1999.9923706054688,
"shortLink": "izoqvWJk",
"badges": {
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"comments": 0,
"attachments": 0,
"description": false,
"due": "2016-12-26T11:00:00.000Z",
"dueComplete": false
},
"dueComplete": false,
"due": "2016-12-26T11:00:00.000Z",
"idChecklists": [],
"idMembers": ["54f0cc079bf18f2798dda8bd"],
"labels": [{
"id": "57873ba984e677fd3683bef8",
"idBoard": "57873ba94794058756fa0a96",
"name": "Urgent",
"color": "red",
"uses": 14
}],
"shortUrl": "https://trello.com/c/vfvfdvdfv",
"subscribed": false,
"url": "https://trello.com/c/fdvfdvdfv/cfvdfv"
},
{
"id": "5832c2fa7f55fe5637d972ea",
"checkItemStates": null,
"closed": false,
"dateLastActivity": "2016-12-30T09:25:09.222Z",
"desc": "",
"descData": null,
"idBoard": "57873ba94794058756fa0a96",
"idList": "57873bb3a725f734089702b2",
"idMembersVoted": [],
"idShort": 80,
"idAttachmentCover": null,
"manualCoverAttachment": false,
"idLabels": ["57873ba984e677fd3683bef6"],
"name": "other card name",
"pos": 2023.9922790527344,
"shortLink": "XhUPgcsD",
"badges": {
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"comments": 0,
"attachments": 0,
"description": false,
"due": "2016-12-30T15:00:00.000Z",
"dueComplete": false
},
"dueComplete": false,
"due": "2016-12-30T15:00:00.000Z",
"idChecklists": [],
"idMembers": ["54fdbe1a8ecdf184596c7c07"],
"labels": [{
"id": "57873ba984e677fd3683bef6",
"idBoard": "57873ba94794058756fa0a96",
"name": "Medium",
"color": "yellow",
"uses": 1
}],
"shortUrl": "https://trello.com/c/XhdfvdfvUPgcsD",
"subscribed": false,
"url": "https://trello.com/c/XhUPgcsfdvdffvD/
"
But I cannot correctly count idList -> and I'm trying to get number of cards in a list, by using Response.Data("idList").Count
Any information how to do it proper way? or which is the best way to parse JSON data?
General:
Your JSON isn't properly closed. I added }] to the end to close and placed in cell A1 of activesheet (as I don't have the API info). I then read that in from the cell as if it were response text.
Process:
I then used JSONConverter to parse this string from the sheet. This requires you to also add a reference to Microsoft Scripting Runtime via VBE > Tools > References.
The returned object is a collection of dictionaries. I test each dictionary for the existence of an idList key and if present add 1 to the variable itemCount, which keeps track of how many idLists there are.
Code:
Public Sub GetInfoFromSheet()
Dim jsonStr As String, item As Object, json As Object, itemCount As Long
jsonStr = [A1]
Set json = JsonConverter.ParseJson(jsonStr)
For Each item In json 'collection
If item.Exists("idList") Then itemCount = itemCount + 1
Next item
Debug.Print "idList count: " & itemCount
End Sub

Using DataContractJsonSerializer To Parse JSON To Dynamic Type In VB.NET

I am using VB.NET to parse my SearchSpring JSON like this:
Using ms As New MemoryStream(Encoding.Unicode.GetBytes(json))
Dim serializer As DataContractJsonSerializer = New DataContractJsonSerializer(obj.GetType())
obj = CType(serializer.ReadObject(ms), T)
Return obj
End Using
The problem is that JSON has different types for same attribute name ("value"):
{
"field": "vanity_style_63",
"value": "Transitional",
"label": "Vanity Style: Transitional",
"filterLabel": "Vanity Style",
"filterValue": "Transitional"
},
{
"field": "vanity_width_88",
"value": {
"rangeLow": "15",
"rangeHigh": "24"
},
"label": "Vanity Width: 16\" to 24\"",
"filterLabel": "Vanity Width",
"filterValue": "16\" to 24\""
},
Sometimes it is string (in example - "Transitional"), sometimes it is an object.
I am using this class in serialization.
<DataContract()> _
Public Class FilterSummary
<DataMember(Name:="field")> _
Public Property Field As String
<DataMember(Name:="filterLabel")> _
Public Property FilterLabel As String
<DataMember(Name:="filterValue")> _
Public Property FilterValue As String
<DataMember(Name:="label")> _
Public Property Label As String
<DataMember(Name:="value")> _
Public Property Value As Object
End Class
It works when I have string there. However, when JSON has object there, I cannot access its values.
What should I do?
UPDATE:
This is how full valid JSON looks like:
{
"filterSummary": [{
"field": "vanity_width_88",
"value": {
"rangeLow": "15",
"rangeHigh": "24"
},
"label": "Vanity Width: 16\" to 24\"",
"filterLabel": "Vanity Width",
"filterValue": "16\" to 24\""
}, {
"field": "vanity_width_88",
"value": {
"rangeLow": "35",
"rangeHigh": "42"
},
"label": "Vanity Width: 35 to 42",
"filterLabel": "Vanity Width",
"filterValue": "35 to 42"
}]
}

VB.NET need help in deserialization of a JSON

Hey I need help in deserializing this:
{
"success": true,
"rgInventory": {
"2722309060": {
"id": "2722309060",
"classid": "939801430",
"instanceid": "188530139",
"amount": "1",
"pos": 1
},
"2722173409": {
"id": "2722173409",
"classid": "937254203",
"instanceid": "188530139",
"amount": "1",
"pos": 2
},
"2721759518": {
"id": "2721759518",
"classid": "720293857",
"instanceid": "188530139",
"amount": "1",
"pos": 3
},
"2721748390": {
"id": "2721748390",
"classid": "310777652",
"instanceid": "480085569",
"amount": "1",
"pos": 4
}
}
}
at the end it should look like:
2722309060#2722173409#2721759518#2721748390
Dim result = JsonConvert.DeserializeObject(jsonstring) 'deserialize it
Dim tempfo As String = result("rgInventory").ToString 'get rgInventory
Console.WriteLine(tempfo)
how i can deserialize all 'id's?
The json contains a Dictionary of items, the IDs you want are the keys. If you deserialized it, you could get them from the Dictionary. Otherwise, you can use JParse and linq to get them:
Dim jstr As String = ...
' parse the json
Dim js As JObject = JObject.Parse(jstr)
' extract the inventory items
Dim ji As JObject = JObject.Parse(js("rgInventory").ToString)
' get and store the keys
Dim theIds As List(Of String) = ji.Properties.Select(Function(k) k.Name).ToList()
I suspect that when "success" is false that the resulting items list will be empty. Test that it works:
For Each s As String In theIds
Console.WriteLine(s)
Next
Result:
2722309060
2722173409
2721759518
2721748390