user3010090
user3010090

Reputation: 175

Deserializing JSON in Visual basic

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

Upvotes: 12

Views: 113754

Answers (4)

Kannadasan K
Kannadasan K

Reputation: 11

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)

Upvotes: 1

prog2011
prog2011

Reputation: 61

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

Upvotes: 0

valverij
valverij

Reputation: 4941

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

Upvotes: 26

Karl Anderson
Karl Anderson

Reputation: 34846

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.

Upvotes: 9

Related Questions