How to Parse Json in vb.net; want to create bittrex ticker.
Request I made with following code:
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Try
request = DirectCast(WebRequest.Create("https://bittrex.com/api/v1.1/public/getmarketsummary?market=btc-ltc"), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
rawresp = reader.ReadToEnd()
Catch ex As Exception
Console.WriteLine(ex.ToString)
MsgBox(ex.ToString)
Finally
If Not response Is Nothing Then response.Close()
End Try
And i got following json response:
{"success":true,"message":"","result":[{"MarketName":"BTC-LTC","High":0.01670094,"Low":0.01610000,"Volume":47495.02156742,"Last":0.01628948,"BaseVolume":777.22088098,"TimeStamp":"2018-01-21T13:18:23","Bid":0.01624001,"Ask":0.01628948,"OpenBuyOrders":2146,"OpenSellOrders":8104,"PrevDay":0.01622000,"Created":"2014-02-13T00:00:00"}]}
Want value of Last to be shown in textbox, so i tried to parse it with "Newtonsoft" as follows:
Dim jsonArray As JArray = JArray.Parse(rawresp)
For Each item As JObject In jsonArray
textboxLast.Text = item.SelectToken("Last").ToString
Next
But getting error :(
Dim json As String = rawresp
Dim jsonObject As Newtonsoft.Json.Linq.JObject = Newtonsoft.Json.Linq.JObject.Parse(json)
Dim jsonArray As JArray = jsonObject("result")
For Each item As JObject In jsonArray
textboxLast.Text = item.SelectToken("Last").ToString
Next
It has to do with the format of the JSON. it is not an array, but an object that contains an array, so you have to first parse the object, and then take the array out of it to parse properly. You missed that one extra step, which I added in above code snippet
Related
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())
I'm using code below to get data in JSON format using Newtonsoft.Json:
my code to create the JSON is
Dim sb As New StringBuilder()
Dim sw As New StringWriter(sb)
Dim writer As JsonWriter = New JsonTextWriter(sw)
writer.WriteStartArray()
For Each elements As JToken In result
If i = 0 Then
i += 1
Continue For
End If
For Each aaa As JToken In elements
writer.WriteStartObject()
Dim pmid = aaa("uid").Value(Of String)
Dim issn = aaa("issn").Value(Of String)
Dim essn = aaa("essn").Value(Of String)
Dim source = aaa("source").Value(Of String)
Dim sortpubdate = aaa("sortpubdate").Value(Of String)
writer.WritePropertyName("pmid")
writer.WriteValue(pmid)
writer.WritePropertyName("journal")
writer.WriteValue(source)
writer.WritePropertyName("issn")
writer.WriteValue(issn)
writer.WritePropertyName("essn")
writer.WriteValue(essn)
writer.WritePropertyName("sortpubdate")
writer.WriteValue(sortpubdate)
writer.WritePropertyName("pubYear")
writer.WriteEndObject()
Next
Next
writer.Close()
Return sb.ToString
and the output code is
public HttpResponseMessage Get()
{
string yourJson = GetJsonFromSomewhere();
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
return response;
}
My current output is.
[{"pmid":"29241721","issn":"0749-3797","essn":"1873-2607","journal":"Am J Prev Med","pubYear":"2018","ImpactFactor":" 4.127"},{"pmid":"28987617","issn":"0166-4328","essn":"1872-7549","journal":"Behav Brain Res","pubYear":"2018","ImpactFactor":" 3.173"},
Is there a way I can indent my output?
[{
"pmid": "29241721",
"issn": "0749-3797",
"essn": "1873-2607",
"journal": "Am J Prev Med",
"pubYear": "2018",
"ImpactFactor": " 4.127"
}, {
Is there a way I can do it like below?
this.SerializerSettings.Formatting = Formatting.Indented;
The client side is just a simple browser URL that get a response
You should indent your object in serialization time and then use it everywhere you want. If GetJsonFormatSomewhere() is your serialization method you should seralize your object in that method below:
var serializedObject = JsonConvert.SerializeObject(data, Formatting.Indented);
and then pass indented object to StringContent method.
Note: it's better to indent your output in client side, that way your packet size will stay small and it's performance friendly.
I got what I needed with
Dim writer As JsonWriter = New JsonTextWriter(sw)
writer.Formatting = Newtonsoft.Json.Formatting.Indented
Here is the JSON content that needs to be posted.
{
"getcart": {
"version": "1.0",
"account": "6566",
"username": "112",
"password": "xxxxxxxx",
"cartid": "57044d79",
} }
Code:
Dim jsonPost As New JsonPost("https://www.example.aspx")
Dim dictData As New Dictionary(Of String, Object)
dictData.Add("version", "1.0")
dictData.Add("account", "6566")
dictData.Add("username", "112")
dictData.Add("password", "xxxxxxxx")
dictData.Add("cartid", "57044d79")
Dim json As JObject = JObject.Parse(JsonPost.postData(dictData))
Dim response As String = JsonPost.postData(dictData)
MsgBox(response)
The error I'm getting:
Error reading JObject from JsonReader. Path'',line 0 postion 0
How can I fix this?
I couldn't do it using the dictionary. But I was able to post it as a string.
The main issue was declaring a JSON string that contains an object in Visual Basic. Here is how I did it:
Dim JsonData As String = "{'getcart':{
'version':'1.0',
'account':'6566',
'username':'112',
'password':'xxxxxxxx',
'cartid':'57044d79',
}}"
Dim Uri As String = "https://www."
Dim data = Encoding.UTF8.GetBytes(JsonData)
Dim result_post = SendRequest(New Uri(Uri), data, "application/json", "POST")
MsgBox(result_post)
Private Function SendRequest(uri As Uri, jsonDataBytes As Byte(), contentType As String, method As String) As String
Dim req As WebRequest = WebRequest.Create(uri)
req.ContentType = contentType
req.Method = method
req.ContentLength = jsonDataBytes.Length
Dim stream = req.GetRequestStream()
stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
stream.Close()
Dim response = req.GetResponse().GetResponseStream()
Dim reader As New StreamReader(response)
Dim res = reader.ReadToEnd()
reader.Close()
response.Close()
Return res
End Function
I'm new to VB.NET and am working on a simple program that will serialize two variables into JSON and POST the data to a web server. The data is being received by the Python server but it is giving an error when trying to deserialize the data.
The inputs are:
tester_id = 2
operation = "P"
When serialized this looks like:
{
"tester_id": 2,
"operation": "P"
}
Our server is giving an error and has the following log.
[Sat Aug 19 13:46:53.485257 2017] [:error] [pid 17352] <QueryDict: {u'{\\r\\n "tester_id": 2,\\r\\n "operation": "P"\\r\\n}': [u'']}>
This suggests that it is receiving a key of:
{u'{\\r\\n "tester_id": 2,\\r\\n "operation": "P"\\r\\n}
With a value of:
[u'']
This isn't correct and I don't understand why it is being received like this, any help is greatly appreciated! See below for the VB.NET code.
Class:
Public Class JSON_get_sensor_id_POST
Public Property tester_id() As Integer
Get
Return m_tester_id
End Get
Set(ByVal value As Integer)
m_tester_id = value
End Set
End Property
Private m_tester_id As Integer
Public Property operation() As String
Get
Return m_operation
End Get
Set(ByVal value As String)
m_operation = value
End Set
End Property
Private m_operation As String
End Class
Call function:
Dim set_tester_id As Integer = 1
Dim set_operation As String = "P"
Dim manuf_url As String = "https://XYZ...."
Dim JSON_to_send As New JSON_get_sensor_id_POST
JSON_to_send.tester_id = set_tester_id
JSON_to_send.operation = set_operation
Dim postData = JsonConvert.SerializeObject(JSON_to_send, Formatting.Indented)
Dim return_object = POST_to_Server(manuf_url, postData)
Upload Function:
Private Function POST_to_Server(ByVal post_url As String, ByVal JSON_to_post As Object)
Dim user_login As String = "blah#blah.com"
Dim user_pass As String = "blah"
Dim myCache As New CredentialCache()
myCache.Add(New Uri(post_url), "Basic", New NetworkCredential(user_login, user_pass))
' Create a request using a URL that can receive a post.
Dim request As WebRequest = WebRequest.Create(post_url)
' Set the Method property of the request to POST.
request.Credentials = myCache
request.Method = "POST"
request.ContentType = "application/json"
' Create POST data and convert it to a byte array.
Dim byteArray As Byte() = Encoding.Default.GetBytes(JSON_to_post)
' Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length
' Get the request stream.
Dim dataStream As Stream = request.GetRequestStream()
' Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length)
' Close the Stream object.
dataStream.Close()
' Get the response.
Dim response As WebResponse = request.GetResponse()
' Display the status.
Console.WriteLine(CType(response, HttpWebResponse).StatusDescription)
' Get the stream containing content returned by the server.
dataStream = response.GetResponseStream()
' Open the stream using a StreamReader for easy access.
Dim reader As New StreamReader(dataStream)
' Read the content.
Dim responseFromServer As String = reader.ReadToEnd()
' Display the content.
DebugMessage(responseFromServer)
' Clean up the streams.
reader.Close()
dataStream.Close()
response.Close()
Dim myObject = JsonConvert.DeserializeObject(Of JSON_sensor_id_request_return)(responseFromServer)
Return myObject
End Function
\r and \n are escape sequences that are not visible when a string is displayed. Instead of formatting your data like this:
{
"tester_id": 2,
"operation": "P"
}
try formatting it something like this:
{"tester_id": 2,"operation": "p"}
I have this code in my project:
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
request = DirectCast(WebRequest.Create("https://url.to.my.json"), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
Dim rawresp As String
rawresp = reader.ReadToEnd()
textbox2.text = rawresp
and TextBox2 gets the JSON code correctly.
and this is my JSON code example:
{
"id":174543706,
"first_name":"Hamed",
"last_name":"Ap",
"username":"hamed_ap",
"type":"private"
}
My question:
How to get 174543706 from JSON code ("id") into TextBox3.Text???
You could use JavaScriptSerializer which is in System.Web.Script.Serialization.
Imports System.Web.Script.Serialization
Module Module1
Sub Main()
Dim s As String
Try
Dim rawresp As String = "{""id"":174543706,""first_name"":""Hamed"",""last_name"":""Ap"",""username"":""hamed_ap"",""type"":""private""}"
Dim jss As New JavaScriptSerializer()
Dim dict As Dictionary(Of String, String) = jss.Deserialize(Of Dictionary(Of String, String))(rawresp)
s = dict("id")
Catch ex As Exception
End Try
End Sub
End Module
try this code :
Dim jsonResulttodict = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(rawresp)
Dim firstItem = jsonResulttodict.item ("id")
hope it help you !!
How to get 174543706 from JSON code ("id") into TextBox3.Text?
{
"id": 174543706,
"first_name": "Hamed",
"last_name": "Ap",
"username": "hamed_ap",
"type": "private"
}
Sorry if my reply was late. I hope my answer can help someone who's still confused.
So what you do was get the response and read the JSON.
After you do ReadToEnd():
Dim xr As XmlReader = XmlReader.Create(New StringReader(rawresp))
Dim doc As XmlDocument = New XmlDocument()
doc.LoadXml(rawresp)
Then What you need to do is to read the data from the response. you do like this:
Dim res As String = JsonConvert.SerializeXmlNode(doc)
Dim ThisToken As JObject = Newtonsoft.Json.JsonConvert.DeserializeObject(Of JObject)(res)
Dim response As String = ThisToken("response").ToString()
Dim ThisData As JObject = Newtonsoft.Json.JsonConvert.DeserializeObject(Of JObject)(response)
After that yo can get the data from the response and convert it into string
Dim idx As String = ThisData("id").ToString()
// the value of idx will be: 174543706
Then last you can put it into Texbox3.Text.
JSON can be parsed using adding Newtonsoft.Json.dll reference
Code :
Imports System.Net
Imports Newtonsoft.Json.Linq
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim json As String = New System.Net.WebClient().DownloadString("http://time.jsontest.com/")
Dim parsejson As JObject = JObject.Parse(json)
Dim thedate = parsejson.SelectToken("date").ToString()
txt1.Text = "Date Is "+thedate
End Sub
End Class
Reference : Narendra Dwivedi - Parse JSON
This works:
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
request = DirectCast(WebRequest.Create("https://url.to.my.json"), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
Dim rawresp As String
rawresp = reader.ReadToEnd()
textbox2.text = JObject.Parse(rawresp)("id")