I'm receiving this JSON from my WebMethod:
{
"TableName": "myTable",
"Table": [
{
"ProdOrder": "245392",
"Item": "C01000FLS0300GF",
"Qty": 40
},
{
"ProdOrder": "245393",
"Item": "C01000FLS0400GF",
"Qty": 20
}
]
}
This is the WebMethod:
<WebMethod()>
Public Function MyWebMethod(strJSON As String) As String
Dim objJSON As Object = New JavaScriptSerializer().Deserialize(Of Object)(strJSON)
'Get TableName
Dim strTableName As String = objJSON("TableName")
'Get Data
Dim arrJSON As Object() = objJSON("Table")
For i As Integer = 0 To arrJSON.Length - 1
Dim ProdOrder As String = arrJSON(i)("ProdOrder")
Dim Item As String = arrJSON(i)("Item")
Dim Qty As String = arrJSON(i)("Qty")
Next
Return "OK"
End Function
Until here all is very simple and it works.
My question now is, how can I get the Names of the fields if I don't know them?
I mean, any way to get "ProdOrder", "Item" and "Qty"...
Using arrJSON(i)("ProdOrder") I get the Value. How can I get the title "ProdOrder"?
I found a way to do it:
Public Function MyWebMethod(strJSON As String) As String
Dim objJSON As Object = New JavaScriptSerializer().Deserialize(Of Object)(strJSON)
Dim strTableName, strFields, strValues As String
For Each JSONItem As KeyValuePair(Of String, Object) In objJSON
Select Case JSONItem.Key
Case "TableName"
'Get TableName
strTableName = JSONItem.Value
Case "Table"
'Get Data
For Each DataRecord As Object In JSONItem.Value
strFields = ""
strValues = ""
For Each DataField As KeyValuePair(Of String, Object) In DataRecord
strFields &= DataField.Key & ","
strValues &= DataField.Value & ","
Next
Next
End Select
Next
Return "OK"
End Function
I am struggling to fill a DataGridView from a JSON that I get through a webrequest to SOLR.
JSON Example:
{
"response":{"numFound":6,"start":1,"docs":[
{
"PRODUCTNAME":"Office Chair",
"CURRENCYCODE":"EUR",
"CLIENTCODE":"Northwind Inc",
"LANGUAGECODE":"ENG",
"KEYWORDS":"spins, adjust, castors"}]
}}
The below will work and get one token and put it in a label.
Code:
Private Sub SOLR()
Label2.Text = Nothing
Try
Dim fr As WebRequest
Dim targetURI As New Uri("LinkToJson")
fr = DirectCast(WebRequest.Create(targetURI), WebRequest)
fr.Credentials = New NetworkCredential("admin", "admin")
If (fr.GetResponse().ContentLength > 2) Then
Dim str As New StreamReader(fr.GetResponse().GetResponseStream())
Dim streamText As String = str.ReadToEnd()
Dim myJObject = JObject.Parse(streamText)
Label2.Text = myJObject.SelectToken("response.docs[0].KEYWORDS")
Label3.Text = streamText
End If
Catch ex As WebException
MessageBox.Show(ex.ToString())
End Try
End Sub
I tried to deserialize it, but I get an error for the below:
Dim table As DataTable = JsonConvert.DeserializeObject(Of DataTable)(streamText)
DataGridView1.DataSource = myJObject
Newtonsoft.Json.JsonSerializationException: 'Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1.'
You need to pass the "docs" array to the DeserializeObject function in order to load the JSON data into DataTable.
Dim myJObject = JObject.Parse(streamText)
Dim arr = myJObject("response")("docs")
Dim table = JsonConvert.DeserializeObject(Of DataTable)(arr.ToString())
Im looking to get a list of all the devices on my work admin teamviewer account using vb.net. I would also like to be able to change the "Alias" of a given device using it's device id. i know very little about API's. i found the following example but i am not sure how to adapt it to get the json response.
instead of the accesstoken, i believe i need to use the client id and secret id along with the authorization code in order to use this. if i run it in it's current start i get a 401 unauthorized error. Any help would be appreciated.
i also have no idea how to use "PUT" to change the Alias using the device id which will both be entered in textboxes. ex alias = textbox1.text and device_id = textbox2.text
Private Sub SurroundingSub()
Dim accessToken As String = "xxxxxxxxxxxxxxxxxxx"
Dim apiVersion As String = "v1"
Dim tvApiBaseUrl As String = "https://webapi.teamviewer.com"
Dim address As String = tvApiBaseUrl & "/api/" & apiVersion & "/devices"
Try
Dim request As HttpWebRequest = TryCast(WebRequest.Create(address), HttpWebRequest)
request.Headers.Add("Bearer", accessToken)
request.Method = "GET"
Dim webResp As WebResponse = request.GetResponse()
Catch __unusedException1__ As Exception
msgbox(__unusedException1__.ToString)
End Try
End Sub
Here is the Get all devices code:
Private Sub get_teamviewer_devices()
Dim accessToken As String = "XXXXXXXXXXXXXXXXXXXXX"
Dim apiVersion As String = "v1"
Dim tvApiBaseUrl As String = "https://webapi.teamviewer.com"
Dim address As String = tvApiBaseUrl & "/api/" & apiVersion & "/devices"
Dim result_json As String = Nothing
Try
Dim request As HttpWebRequest = TryCast(WebRequest.Create(address), HttpWebRequest)
request.Headers.Add("Authorization", "Bearer " & accessToken)
request.Method = "GET"
Dim webResp As WebResponse = request.GetResponse()
Using reader = New StreamReader(webResp.GetResponseStream)
result_json = reader.ReadToEnd()
End Using
TextBox1.Text = result_json
Catch __unusedException1__ As Exception
MsgBox(__unusedException1__.ToString)
End Try
End Sub
Here is the PUT portion to change an alias:
Public Sub change_alias(ByVal device_id As String, ByVal alias_str As String)
Dim accessToken As String = "XXXXXXXXXXXXXXXXXXXXX"
Dim apiVersion As String = "v1"
Dim tvApiBaseUrl As String = "https://webapi.teamviewer.com"
Dim address As String = tvApiBaseUrl & "/api/" & apiVersion & "/devices/" & device_id
Dim result As String
Dim alias_str_ As String = Chr(34) & alias_str & Chr(34)
Try
Dim request As HttpWebRequest = TryCast(WebRequest.Create(address), HttpWebRequest)
request.Headers.Add("Authorization", "Bearer " & accessToken)
request.Method = "PUT"
request.ContentType = "application/json"
Using requestWriter2 As New StreamWriter(request.GetRequestStream())
requestWriter2.Write("{""Alias"" : " & alias_str_ & "}")
End Using
Dim webResp As WebResponse = request.GetResponse()
Using reader = New StreamReader(webResp.GetResponseStream)
result = reader.ReadToEnd()
End Using
TextBox1.Text = (result)
Catch __unusedException1__ As Exception
MsgBox(__unusedException1__.ToString)
End Try
End Sub
Basically, I'm trying to parse the comments from a 4chan thread using the 4chan JSON API. https://github.com/4chan/4chan-API
basically, there is one rich text box called input, and another called post_text_box. What im trying to do is make it so that JSON from a 4chan thread entered in the input text box, and comments are extracted from that JSON and displayed in the output text box
however, whenever I try clicking the Go button nothing happens.
Here is my code so far
Imports System.Web.Script.Serialization
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class Form1
Private Sub start_button_Click(sender As Object, e As EventArgs) Handles start_button.Click
Dim j As Object = New JavaScriptSerializer().Deserialize(Of Post)(input.Text)
post_text_box.Text = j.com
End Sub
End Class
Public Class Rootobject
Public Property posts() As Post
End Class
Public Class Post
Public Property no As Integer
Public Property now As String
Public Property name As String
Public Property com As String
Public Property filename As String
Public Property ext As String
Public Property w As Integer
Public Property h As Integer
Public Property tn_w As Integer
Public Property tn_h As Integer
Public Property tim As Long
Public Property time As Integer
Public Property md5 As String
Public Property fsize As Integer
Public Property resto As Integer
Public Property bumplimit As Integer
Public Property imagelimit As Integer
Public Property replies As Integer
Public Property images As Integer
End Class
Since you're importing Newtonsoft.Json, you can just use the JsonConvert.DeserializeObject<T>(String) method:
Dim exampleJson As String = "{ 'no':'123', 'name':'Some Name', 'com':'This is a comment'}"
Dim post As Post = JsonConvert.DeserializeObject(Of Post)(exampleJson)
Dim com As String = post.com
post_text_box.Text = com
Alternatively, if you don't want to create a class for Post, you can use JsonConvert.DeserializeAnonymousType<T>(String, T):
Dim exampleJson As String = "{ 'no':'123', 'name':'Some Name', 'com':'This is a comment'}"
Dim tempPost = New With {Key .com = ""}
Dim post = JsonConvert.DeserializeAnonymousType(exampleJson, tempPost)
Dim com As String = post.com
post_text_box.Text = com
EDIT: It looks like you're getting an array back from the API:
{
"posts" : [{
"no" : 38161812,
"now" : "11\/19\/13(Tue)15:18",
"name" : "Anonymous",
"com" : "testing thread for JSON stuff",
"filename" : "a4c",
"ext" : ".png",
"w" : 386,
"h" : 378,
"tn_w" : 250,
"tn_h" : 244,
"tim" : 1384892303386,
"time" : 1384892303,
"md5" : "tig\/aNmBqB+zOZY5upx1Fw==",
"fsize" : 6234,
"resto" : 0,
"bumplimit" : 0,
"imagelimit" : 0,
"replies" : 0,
"images" : 0
}
]
}
In that case, you will need to change the type that is being deserialized to Post():
First, add another small wrapper class:
Public Class PostWrapper
Public posts() As Post
End Class
Then adjust your deserialization code:
Dim json As String = input_box.Text
Dim postWrapper = JsonConvert.DeserializeObject(Of PostWrapper)(json) ' Deserialize array of Post objects
Dim posts = postWrapper.posts
If posts.Length = 1 Then ' or whatever condition you prefer
post_text_box.Text = posts(0).com
End If
Instead of needing to define a class, you can deserialize the JSON into an Object, like this:
Dim json As String = "{""items"":[{""Name"":""John"",""Age"":""20"",""Gender"":""Male""},{""Name"":""Tom"",""Age"":""25"",""Gender"":""Male""},{""Name"":""Sally"",""Age"":""30"",""Gender"":""Female""}]}"
Dim jss = New JavaScriptSerializer()
Dim data = jss.Deserialize(Of Object)(json)
Now, as an example, you could loop through the deserialized JSON and build an HTML table, like this:
Dim sb As New StringBuilder()
sb.Append("<table>" & vbLf & "<thead>" & vbLf & "<tr>" & vbLf)
' Build the header based on the keys of the first data item.
For Each key As String In data("items")(0).Keys
sb.AppendFormat("<th>{0}</th>" & vbLf, key)
Next
sb.Append("</tr>" & vbLf & "</thead>" & vbLf & "<tbody>" & vbLf)
For Each item As Dictionary(Of String, Object) In data("items")
sb.Append("<tr>" & vbLf)
For Each val As String In item.Values
sb.AppendFormat(" <td>{0}</td>" & vbLf, val)
Next
Next
sb.Append("</tr>" & vbLf & "</tbody>" & vbLf & "</table>")
Dim myTable As String = sb.ToString()
Disclaimer: I work with C# on a daily basis and this is a C# example using dynamic that was converted to VB.NET, please forgive me if there are any syntax errors with this.
Note:
First you have to install Newtonsoft.Json on nuget console. Then include following code on top of your code.
Imports Newtonsoft.Json
Step:1 Create class with get & set properties.
Public Class Student
Public Property rno() As String
Get
Return m_rno
End Get
Set(value As String)
m_rno = value
End Set
End Property
Private m_rno As String
Public Property name() As String
Get
Return m_name
End Get
Set(value As String)
m_name = value
End Set
End Property
Private m_name As String
Public Property stdsec() As String
Get
Return m_StdSec
End Get
Set(value As String)
m_StdSec = value
End Set
End Property
Private m_stdsec As String
End Class
Step: 2 Create string as a json format and conver as a json object model.
Dim json As String = "{'rno':'09MCA08','name':'Kannadasan Karuppaiah','stdsec':'MCA'}"
Dim stuObj As Student = JsonConvert.DeserializeObject(Of Student)(json)
Step: 3 Just traverses by object.entity name as follows.
MsgBox(stuObj.rno)
MsgBox(stuObj.name)
MsgBox(stuObj.stdsec)
Also, if you have complex json string. If there is subclasses, arrays, etc. in the json string, you can use this way at below. I tried it and it worked for me. I hope it will useful for you.
I accessed root->simpleforecast->forecastday[]->date->hight->celsius,fahrenheit values etc. in the json string.
Dim tempforecast = New With {Key .forecast = New Object}
Dim sFile As String = SimpleTools.RWFile.ReadFile("c:\\testjson\\test.json")
Dim root = JsonConvert.DeserializeAnonymousType(sFile, tempforecast)
Dim tempsimpleforecast = New With {Key .simpleforecast = New Object}
Dim forecast = jsonConvert.DeserializeAnonymousType(root.forecast.ToString(), tempsimpleforecast)
Dim templstforecastday = New With {Key .forecastday = New Object}
Dim simpleforecast = JsonConvert.DeserializeAnonymousType(forecast.simpleforecast.ToString(), templstforecastday)
Dim lstforecastday = simpleforecast.forecastday
For Each jforecastday In lstforecastday
Dim tempDate = New With {Key .date = New Object, .high = New Object, .low = New Object}
Dim forecastday = JsonConvert.DeserializeAnonymousType(jforecastday.ToString(), tempDate)
Dim tempDateDetail = New With {Key .day = "", .month = "", .year = ""}
Dim fcDateDetail = JsonConvert.DeserializeAnonymousType(forecastday.date.ToString(), tempDateDetail)
Weather_Forcast.ForcastDate = fcDateDetail.day.ToString() + "/" + fcDateDetail.month.ToString() + "/" + fcDateDetail.year.ToString()
Dim temphighDetail = New With {Key .celsius = "", .fahrenheit = ""}
Dim highDetail = JsonConvert.DeserializeAnonymousType(forecastday.high.ToString(), temphighDetail)
Dim templowDetail = New With {Key .celsius = "", .fahrenheit = ""}
Dim lowDetail = JsonConvert.DeserializeAnonymousType(forecastday.low.ToString(), templowDetail)
Weather_Forcast.highCelsius = Decimal.Parse(highDetail.celsius.ToString())
Weather_Forcast.lowCelsius = Decimal.Parse(lowDetail.celsius.ToString())
Weather_Forcast.highFahrenheit = Decimal.Parse(lowDetail.fahrenheit.ToString())
Weather_Forcast.lowFahrenheit = Decimal.Parse(lowDetail.fahrenheit.ToString())
Weather_Forcast09_Result.Add(Weather_Forcast)
Next
I need to filter where clause in my GetProduct function using http request query string property. I have set up my filters in urls. (eg burgers.aspx?filter=burgers'). Burgers is the name of database table category(Where ProductCat = filter). I understand I need to pass parameter to interaction class because it does not handle requests. Please help.
Interaction class:
Public Class Interaction
Inherits System.Web.UI.Page
' New instance of the Sql command object
Private cmdSelect As New SqlCommand
' Instance of the Connection class
Private conIn As New Connection
Region "Menu functions and subs"
' Set up the SQL statement for finding a Product by ProductCat
Private Sub GetProduct(ByVal CatIn As String)
' SQL String
Dim strSelect As String
strSelect = "SELECT * "
strSelect &= " FROM Menu "
strSelect &= " WHERE ProductCat = "
strSelect &= "ORDER BY 'ProductCat'"
' Set up the connection to the datebase
cmdSelect.Connection = conIn.Connect
' Add the SQL string to the connection
cmdSelect.CommandText = strSelect
' Add the parameters to the connection
cmdSelect.Parameters.Add("filter", SqlDbType.NVarChar).Value = CatIn
End Sub
'Function to create list of rows and columns
Public Function ReadProduct(ByVal CatIn As String) As List(Of Dictionary(Of String, Object))
'Declare variable to hold list
Dim ReturnProducts As New List(Of Dictionary(Of String, Object))
Try
Call GetProduct(CatIn)
Dim dbr As SqlDataReader
' Execute the created SQL command from GetProduct and set to the SqlDataReader object
dbr = cmdSelect.ExecuteReader
'Get number of columns in current row
Dim FieldCount = dbr.FieldCount()
Dim ColumnList As New List(Of String)
'Loop through all columns and add to list
For i As Integer = 0 To FieldCount - 1
ColumnList.Add(dbr.GetName(i))
Next
While dbr.Read()
'Declare variable to hold list
Dim ReturnProduct As New Dictionary(Of String, Object)
'Loop through all rows and add to list
For i As Integer = 0 To FieldCount - 1
ReturnProduct.Add(ColumnList(i), dbr.GetValue(i).ToString())
Next
'Add to final list
ReturnProducts.Add(ReturnProduct)
End While
cmdSelect.Parameters.Clear()
'Close connection
dbr.Close()
Catch ex As SqlException
Dim strOut As String
strOut = ex.Message
Console.WriteLine(strOut)
End Try
' Return the Product object
Return ReturnProducts
End Function
Code Behind:
Partial Class Burger
Inherits System.Web.UI.Page
'String Used to build the necessary markup and product information
Dim str As String = ""
''Var used to interact with SQL database
Dim db As New Interaction
' New instance of the Sql command object
Private cmdSelect As New SqlCommand
' Instance of the Connection class
Private conIn As New Connection
Protected Sub printMenuBlock(ByVal productName As String)
'Set up variable storing the product and pull from databse
Dim product = db.ReadProduct(productName)
'Add necessary markup to str variable, with products information within
For i As Integer = 0 To product.Count - 1
str += "<div class='menuItem'>"
'str += " <img alt='Item Picture' class='itemPicture' src='" + product(i).ImagePath.Substring(3).Replace("\", "/") + "' />"
str += " <div class='itemInfo'>"
str += " <h1 class='itemName'>"
str += " " + product(i).Item("ProductName") + "</h1>"
'str += " <h3 class='itemDescription'>"
str += " " + product(i).Item("ProductDescription")
str += " <h1 class ='itemPrice'>"
str += " " + product(i).Item("ProductPrice") + "</h1>"
str += " "
str += " </div>"
str += " </div>"
Next
End Sub
''Uses
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Dim v = Request.QueryString("filter")
'Response.Write("filter is")
'Response.Write(v)
Dim value = Request.QueryString("filter")
'Get string from printMenuBlock method
printMenuBlock(str)
'Print the str variable in menuPlace div
menuPlace.InnerHtml = str
End Sub
End Class
I need a direction on how to pass the Request.QueryString("filter") to GetProduct function to filter by page according to ProductCategory. Thanks in advance.
Try something like this:
Dim filter = Request.QueryString("filter")
Dim sqlStr = "Select * From menu Where ProductCat = #filter Order By ProductCat"
cmdSelect.Parameters.Add("filter", SqlDbType.NVarChar).Value = filter