This is my first dealing with JSON and unfortunately I have to do it in VB.Net, company policy. So I have searched high and low and tried a lot of examples even converted some of the C# code to VB.Net but I can't seem to find a complete solution.
I receive a JSON string like this:
{
"65080007":{
"partNo":"ATD000007",
"description":"Swingarm Hat Platform",
"quantity":4,
"assemblyseq":""
},
"65080143":{
"partNo":"ATD000143",
"description":"ASY Gas Spring Bracket",
"quantity":2,
"assemblyseq":""
},
"65080071":{
"partNo":"ATD000071",
"description":"TT Gas Spring",
"quantity":2,
"assemblyseq":""
},
"65080147":{
"partNo":"ATD000147",
"description":"ASY Lateral Hinge",
"quantity":8,
"assemblyseq":""
},
"65085181":{
"partNo":"RD0181",
"description":"ASY KIT Bolt, Carriage, 0.375 in x 16, 1.5 in (x45) & Nut, Flange, 0.375 in x 16 (x45)",
"quantity":1,
"assemblyseq":""
},
"65080796":{
"partNo":"ATD000796",
"description":"Decal, TT Equipped, Rectangular, 5 in x 10 in",
"quantity":1,
"assemblyseq":""
},
"65080797":{
"partNo":"ATD000797",
"description":"Decal, TT Open/Close, Triangular, 12 in x 8 in",
"quantity":1,
"assemblyseq":""
},
"65080745":{
"partNo":"ATD000745",
"description":"",
"quantity":1,
"assemblyseq":""
}
}
What I need to do bind or assign this data to a DataGridView.DataSource.
I've seen some examples but I can't set it as a DataSource.
I've tried this example:
Sub Main()
Dim json_result = GetJson()
Dim table = JsonConvert.DeserializeAnonymousType(json_result, (DataTable))
Dim newJString = Newtonsoft.Json.JsonConvert.SerializeObject(table, Newtonsoft.Json.Formatting.Indented)
Console.WriteLine("Re-serialized JSON: ")
Console.WriteLine(newJString)
Console.WriteLine("")
End Sub
Public Function GetJson() As String
Dim json_result As String = <![CDATA[
' I used the above json string
Return json_result
End Function
I have made my JSON classes to deserialise the JSON and tried JsonConvert.Deserialize keep getting an error it epected a array and found an object.
Public Class Jobs
'<JsonProperty("partno")>
Public Property PartNo As String
' <JsonProperty("description")>
Public Property Description As String
'<JsonProperty("quantity")>
Public Property Quantity As String
'<JsonProperty("assemblyseq")>
Public Property Assemblyseq As String
End Class
The issue I think is the root properties "65080797" these numbers will not be the same every time we get the JSON back from NetSuite.
So I tried to:
Dim obj = JsonConvert.DeserializeObject(Of Jobs)(result)
Console.WriteLine(obj.PartNo) it comes out PartNo = nothing
So I've tried this:
Dim resultA = JsonUtil.Deserialize(Of Jobs)(result, ignoreRoot:=True)
Module JsonUtil
Function Deserialize(Of T As Class)(ByVal json As String, ByVal ignoreRoot As Boolean) As T
Return If(ignoreRoot, JObject.Parse(json)?.Properties()?.First()?.Value?.ToObject(Of T)(), JObject.Parse(json)?.ToObject(Of T)())
End Function
End Module
This gives me the first group:
ATD000007
Swingarm Hat Platform
4
The assembly number was blank.
I'm open for any suggestions on how I can get the above JSON into a data table or DataGridView or how to make a list without the root "65080797" this number will be unique with every response.
The people that designed this response string refuses to remove the root properties.
Thank you for taking the time to read this mess.
All comments/suggestions are appreciated.
Yes, Json array looks like [something] instead of {somthing}, you could convert it to array if you want but you can also do it in different ways and even without any external library, you could create a datatable then bind it to datagridview or you could add data directly to datagridview.
Anyway, I made a datatable for you.
Imports System.Web.Script.Serialization 'for reading of JSON (+add the reference to System.Web.Extensions library)
Dim JSONC = New JavaScriptSerializer().Deserialize(Of Dictionary(Of String, Dictionary(Of String, String)))(JSON) 'you could do it in different ways too
Dim NewDT As New DataTable
'Create Columns
For Each key In JSONC.First.Value.Keys
'"65080007" <first
'{ "partNo":"ATD000007", "description":"Swingarm Hat Platform", "quantity":4, "assemblyseq":"" } <first.value
' "partNo" <first.value.key(s) :"ATD000007" <first.value.value(s)
NewDT.Columns.Add(key)
Next
'Add Rows
For Each item In JSONC
NewDT.Rows.Add(item.Value.Values.ToArray)
Next
DataGridView1.DataSource = NewDT
If you have unusually structured JSON like that, your best bet is probably to resort to using raw JObject and JToken handling instead of trying to get JSON.NET to deserialize into structured data automatically.
Create a method that will convert an individual JToken into the Job class you described in your question. I've added a Key property to identify those unique keys in the JSON that were problematic for you; if you don't need these, just remove the .Key bit from the example below.
Public Function CreateJob(data As JToken)
Return New Job With
{
.Key = data.Path,
.PartNo = data("partNo"),
.Description = data("description"),
.Quantity = data("quantity"),
.Assemblyseq = data("assemblyseq")
}
End Function
Once you have Job objects being created, you can walk the entire structure and turn it into an array of jobs with the sample code below.
Dim result As JObject = JsonConvert.DeserializeObject(json)
Dim jobs As Job() = result.Values().Select(Of Job)(AddressOf CreateJob).ToArray()
Once you have an array of Job objects, binding to a DataSource should be trivial.
A small question: i'm using JsonConverter from Github.
(https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas)
Code is working on most of the "GET" request.
Only when the same 'column' is accuring multiple times in the 'ResponseText' then it's not. (like "imei" in the example)
So I need a way to handle a long 'Responsetext' to fill multiple rows in an access db.
Dim Json As Object
Set Json = JsonConverter.ParseJson(xmlhttp.ResponseText)
MsgBox (Json("imei")) 'temp
Error 5: Invalid Procedure or Call Argument.
Any ideas?
Many thanks,
I can only provide a part of the answer, because I cannot recreate it, without the full JSON Response Text:
The response with mutliple values in JSON returns an Object of the type Collection. Hence you have to use a loop to iterate through all responses. Like this:
Dim Json As Object
Set Json = JsonConverter.ParseJson(xmlhttp.ResponseText)
For Each singleJsonItem In Json
'What object type is singleJsonItem? To find out, maybe use:
'MsgBox singleJsonItem("imei")
Next singleJsonItem
You have to find out the object type of the collectionentries to extract the JSON Entry.
Solved like this:
used : https://github.com/VBA-tools/VBA-JSON
and named the module: 'mdl_JsonConverter'
Set Json = mdl_JsonConverter.ParseJson(xmlhttp.ResponseText)
For Each item In Json
input_1 = item("input_1")
input_2 = item("input_2")
'THEN DO SOMETHING WITH VALUES F.E. ADDING THEM IN A TABLE
Next
If you responseText contains a searchRecords list then filter by searchRecords before for each
Set Json = JsonConverter.ParseJson(strResponse)
For Each singleJsonItem In Json("searchRecords")
'What object type is singleJsonItem? To find out, maybe use:
Msgbox singleJsonItem("Name")
Next singleJsonItem
This feels like it should be really simple but I'm a bit stuck. I want to access an API url using Excel VBA. The API gives me a very simple JSON response containing a load id which is used as a parameter in the calling of another API, the other API isn't a problem because I can get the response in either XML or CSV and parse it into Excel.
API Response:
{"loadid":"1234567890"}
All I need to extract from this response is the number "1234567890".
This is what I've tried so far:
Sub getLoadID()
Dim loadID As String
Dim loadIDUrl As String
loadIDUrl = "blah blah"
proxyServer = Worksheets("Sheet1").Range("A1").Value
Set httpReq = CreateObject("WinHttp.WinHttprequest.5.1")
httpReq.Open "GET", loadIDUrl, False
httpReq.setRequestHeader "Content-Type", "text/xml"
httpReq.setProxy 2, proxyServer, ""
httpReq.setTimeouts -1, -1, -1, -1
httpReq.send request
httpReq.ResponseText = loadID
Worksheets("Sheet1").Range("A2").Value = loadID
End Sub
I've tried to put the whole string into a cell just to make sure that Excel is able to obtain the string from the response but going forward will just be happy to store the value as a variable and not write it to the sheet.
The above code runs with no errors, I just don't get the string in cell A2...
Every time I've searched about parsing JSON using Excel VBA everyone recommends to use external libraries but I'm trying to do this at work so I can't use the external libraries.
Cheers
I am using an MVC application to display information about an Issue from a webhook Json Payload. The application runs on real-time functionality (using deserialization and signalr). The application is listening for when the webhook is firing and it will send an email whether the application is running on the browser or not.
How ever the way I would like to keep a record of the information from the application when the Json payload is deserialized automatically insert it into the database so that it can be displayed later.
Public Function PostIssueData(iss As iTable) as ActionResult
Dim db As New Database
db.iTable.Add(iss)
db.SaveChanges()
return view()
End Function
I don't think this way is possible as I am reading in a Json payload so the table would just have null values and insert nothing.
I am reading the data like this:
Dim r As System.IO.StreamReader = New System.IO.StreamReader(HttpContext.Request.InputStream)
Dim rawJson As String = r.ReadToEnd()
Dim iss As rObject = JsonConvert.DeserializeObject(Of rOject)(rawJson)
System.Diagnostics.Trace.TraceError(rawJson)
So I would have to use this data to insert into a database and have it done automatically, how can this be done?
Update - This worked using Entity framework like this.
Dim newIssue As New IssueResultTable
newIssue.issueKey = issue.issue.key
newIssue.status = issue.issue.fields.status.name
Using db As New GartanIssueTrackerEntities
db.IssueResultTables.Add(newIssue)
db.SaveChanges()
End Using
So I searched through most of the getJSON questions and am still unable to find a solution to my problem. My main problem is this: I have a .js file that makes a $.getJSON call to an .aspx page. The .aspx page returns a json object. I've tested the $.getJSON with a demo.js and it works just fine; I'm able to reference the json field. This is not the case with the .aspx page. Here is my code:
.js making the $getJSON call
$.getJSON('updateSlides.aspx', function (json) {
alert("JSON Data: " + json.url);
});
.aspx returning json obj
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim jsonString As String
If Not Page.IsPostBack Then
Dim ws As New wallboardSettings
' pull data values from db here, replace hardcoded values below
ws.duration = 5
ws.imagePath = "Images\slide1.jpg"
ws.url = "slide1.html"
Dim js As JavaScriptSerializer = New JavaScriptSerializer()
jsonString = js.Serialize(ws)
Response.Write(jsonString)
End If
End Sub
I've placed a msgbox in the VB and ran it from my local machine to see my values. It returns the ws property settings in json form, which validated correctly on jsonlint.com.
I've also tried just using an $.ajax call with async: false but it doesn't work. When I use the demo.js, which works, i see the json fields in firebug; this is not the case with the updateSlides.aspx.
Thanks in advance,
Brian
Set the content type headers to application/json from your response.
So it turns out the json wasn't the issue. the aspx page was return json just fine. According to firebug the same aspx page was also returning addition html that was autogenerated. I deleted this html and firebug showed the json data. Thanks for your reponses!