Deserializing JSON in Visual basic - json

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

Related

Getting info from JSON in VB.NET using Json.NET

I need to process this JSON:
{
"companies": [
{
"companyId": "S86jhs89F",
"companyName": "LoremIpsum"
}
],
"response_metadata": {
"next_cursor": 659,
"next_link": "somedata"
} }
How can I get companyId, companyName, next_cursor and next_link using VB.NET?
Update...
I found this...
Dim json As String = "{ ... textJSON ... }"
Dim ser As JObject = JObject.Parse(json)
Dim data As List(Of JToken) = ser.Children().ToList
Dim output As String = ""
For Each grupo As JProperty In data
grupo.CreateReader()
Select Case grupo.Name
Case "companies"
For Each item As JObject In grupo.Values
output += vbCrLf + " -- " + item("companyId").ToString
output += vbCrLf + " -- " + item("companyName").ToString
Next
Case "response_metadata"
Dim dato As JObject = grupo.Value
output += vbCrLf + " -- " + dato("next_cursor").ToString
End Select
Next
I don´t know if this is the optimal way, but it is working...
Visual Studio has a cool feature called Paste JSON as Classes that can be found under Edit > Paste Special > Paste JSON as Classes. If you were to do this, then you would get something that looks like the following:
Public Class Rootobject
Public Property companies() As Company
Public Property response_metadata As Response_Metadata
End Class
Public Class Response_Metadata
Public Property next_cursor As Integer
Public Property next_link As String
End Class
Public Class Company
Public Property companyId As String
Public Property companyName As String
End Class
You can use decorators to make the property names conform to a more .NET style if you wanted:
Public Class Rootobject
<JsonProperty("companies")>
Public Property Companies As IEnumerable(Of Company)
<JsonProperty("response_metadata")>
Public Property ResponseMetadata As Response_Metadata
End Class
Public Class Response_Metadata
<JsonProperty("next_cursor")>
Public Property NextCursor As Integer
<JsonProperty("next_link")>
Public Property NextLink As String
End Class
Public Class Company
<JsonProperty("companyId")>
Public Property CompanyId As String
<JsonProperty("companyName")>
Public Property CompanyName As String
End Class
Now you would use JsonConvert.DeserializeObject to convert the JSON literal to your root object. After that, it's just a matter of getting the required properties:
Dim conversion = JsonConvert.DeserializeObject(Of Rootobject)(literal)
Dim companyId = conversion.Companies.First().CompanyId
Dim companyName = conversion.Companies.First().CompanyName
' etc.
Example: https://dotnetfiddle.net/GiGKwI

How do I create a new JSON object from another JSON object in VB.Net?

I'm using the following code in VB.Net to fetch a set of time and temperature data in JSON format that I will end up charting. I want to convert the JSON data but I only get far as creating the jObject. After that, I get lost. I'll admit, I'm a bit of a newbie!
Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Partial Class public_html_JSON
Inherits System.Web.UI.Page
Public jResults As JObject
Public rawresp As String
Public strStartTime As String = ""
Public strEndTime As String = ""
Public rangeMinutes As Long
Public debugText As String
Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
Dim cstTime As DateTime = TimeZoneInfo.ConvertTimeFromUtc(DateAdd(DateInterval.Day, 0, DateAdd(DateInterval.Hour, 0, Now().ToUniversalTime)), cstZone)request =
Dim url As String = "https://[somesite]?method=queryList4Chart&device.id=17002&endTime=" + strEndTime + "&sensorNumber=-1&startTime=" + strStartTime
request = DirectCast(WebRequest.Create(url), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
rawresp = reader.ReadToEnd()
response = Nothing
jResults = JObject.Parse(rawresp)
But before I send it to the client-side, I want to:
Create a new JSON string using an "x, y" format with timeArray as "x" and dataArray[0] as
"y".
Reduce the number of data points by only keeping times with minutes divisible by 5. (i.e. 5,10,15,etc...)
Here is the data I want to transform:
"dataArray":[
[
{
"value":13.4
},
{
"value":13.2
},
{
"value":13.2
},
{
"value":13.5
}
],
[
{
"value":2.8
},
{
"value":2.8
},
{
"value":2.9
},
{
"value":3.0
}
]
],
"sensorArray":[
"1.TP1(℃)",
"2.TP2(℃)"
],
"timeArray":[
"2019/11/10 14:00:41",
"2019/11/10 14:05:40",
"2019/11/10 14:07:40",
"2019/11/10 14:10:40"
]
}
And I need it in this format:
[
{
"x":2019/11/10 14:00:00,
"y":13.4
},
{
"x":2019/11/10 14:05:00,
"y":13.2
},
{
"x":2019/11/10 14:10:00,
"y":13.5
}
]
How would I go about doing that?
Thanks to Craig's suggestion, here's the final, working code!
Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Partial Class KFPTempsV2
Inherits System.Web.UI.Page
Public strStartTime As String = ""
Public strEndTime As String = ""
Public rangeMinutes As Long
Public debugText As String
Public JSONxy As ArrayList = New ArrayList 'List of JSON strings
Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
Dim cstTime As DateTime = TimeZoneInfo.ConvertTimeFromUtc(DateAdd(DateInterval.Day, 0, DateAdd(DateInterval.Hour, 0, Now().ToUniversalTime)), cstZone)
Dim DeviceList As IEnumerable(Of TemperatureDevice) = GetTemperatureDevices()
Dim rawResp As String
Dim url As String = ""
Dim objXY As New List(Of List(Of XY))
rangeMinutes = 1440
strStartTime = DateAdd(DateInterval.Minute, -rangeMinutes, cstTime).ToString("MM/dd/yyyy\%20HH:mm:00")
strEndTime = cstTime.ToString("MM/dd/yyyy\%20HH:mm:ss")
'Get data from each device
For Each dv As TemperatureDevice In DeviceList
url = "https://www.[somesite].com/deviceDataAction.do?method=queryList4Chart&device.id=" & dv.ID & "&endTime=" + strEndTime + "&sensorNumber=-1&startTime=" + strStartTime
request = DirectCast(WebRequest.Create(url), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
rawResp = reader.ReadToEnd()
response = Nothing
Dim XYList As List(Of XY) = ConvertToXY(JsonConvert.DeserializeObject(Of JSONData)(rawResp))
JSONxy.Add(JsonConvert.SerializeObject(XYList))
objXY.Add(XYList) 'Store XYList for later use
Next
'Populate Current/H/L temperatures
Current1.InnerHtml = objXY(0)(objXY(0).Count - 1).y
High1.InnerHtml = MaxValue(objXY(0)).ToString
Low1.InnerHtml = MinValue(objXY(0)).ToString
Current2.InnerHtml = objXY(1)(objXY(1).Count - 1).y
High2.InnerHtml = MaxValue(objXY(1)).ToString
Low2.InnerHtml = MinValue(objXY(1)).ToString
Current3.InnerHtml = objXY(2)(objXY(2).Count - 1).y
High3.InnerHtml = MaxValue(objXY(2)).ToString
Low3.InnerHtml = MinValue(objXY(2)).ToString
Current4.InnerHtml = objXY(3)(objXY(3).Count - 1).y
High4.InnerHtml = MaxValue(objXY(2)).ToString
Low4.InnerHtml = MinValue(objXY(3)).ToString
End Sub
Function ConvertToXY(obj As JSONData) As List(Of XY)
Dim NewObj As List(Of XY) = New List(Of XY)
For i As Int16 = 0 To obj.DataArray(1).Length - 1
Dim oDate As DateTime = Convert.ToDateTime(obj.TimeArray(i))
Dim oNewDate As DateTime = New DateTime(oDate.Year, oDate.Month, oDate.Day, oDate.Hour, oDate.Minute, 0).AddMinutes(Math.Round(oDate.Second / 60))
If oNewDate.Minute Mod 5 = 0 Then
Dim objXY As XY = New XY
objXY.x = oNewDate.ToString("yyyy/MM/dd HH:mm:ss")
objXY.y = obj.DataArray(1)(i).Value
NewObj.Add(objXY)
End If
Next
Return NewObj
End Function
Function MinValue(oList As List(Of XY)) As String
Dim sglMin As Single = 200
For Each row As XY In oList
Try
If CSng(row.y) < sglMin Then
sglMin = CSng(row.y)
End If
Catch ex As Exception
End Try
Next
Return sglMin.ToString("F1")
End Function
Function MaxValue(oList As List(Of XY)) As String
Dim sglMax As Single = -200
For Each row As XY In oList
Try
If CSng(row.y) > sglMax Then
sglMax = CSng(row.y)
End If
Catch ex As Exception
End Try
Next
Return sglMax.ToString("F1")
End Function
Public Class JSONData
Public Property DataArray As DataArray()()
Public Property SensorArray As String()
Public Property TimeArray As String()
End Class
Public Class DataArray
Public Property Value As String
End Class
Class XY 'Important that xy field names be lowercase
Property x As String
Property y As String
End Class
Public Class TemperatureDevice
Public Name As String
Public ID As String
Public DatasetNum As Int16
Public Sub New()
End Sub
Public Sub New(ByVal _name As String,
ByVal _id As String,
ByVal _datasetNum As Int16
)
Name = _name
ID = _id
DatasetNum = _datasetNum
End Sub
End Class
Private Function GetTemperatureDevices() As IEnumerable(Of TemperatureDevice)
'Dataset choices TP1=0 Or TP2=1
Return New List(Of TemperatureDevice) From
{
New TemperatureDevice("Pump House", "17002", 1),
New TemperatureDevice("Planer", "7199", 1),
New TemperatureDevice("Sawmill", "7123", 1),
New TemperatureDevice("Wellons", "13293", 1)
}
End Function
End Class

How to pass a complex JSON object through VB.net to call Rest API

I have a Rest API which I have to call from my vb.net code.
In the Postman I pass the arguments in the Body as follows:
{
"Search" :
{
"EmpName" : "Rachel",
"EmpID" : "1100320"
},
"IncludeAttributes" : ["EmpId", "EmpName","Department","Salary","ManagerId"]
}
My problem is that I am not sure how can I pass this kind of parameter through my call from VB.Net call.
Here is what I have tried:
Dim searchParameters = New Dictionary(Of String, String)()
searchParameters.Add("EmpName", "Rachel")
searchParameters.Add("EmpID", "1100320")
Dim jsonSearchParameters =
JsonConvert.SerializeObject(searchParameters)
Dim stringContent = New StringContent(jsonSearchParameters, Encoding.UTF8, "application/json")
And now I am clueless of how to pass IncludeAttributes part in the same object.
Any help please?
As #cricket_007 suggests a Dictionary(Of String, Object) would work:
Dim search = New Dictionary(Of String, String) From {
{"EmpName", "Rachel"},
{"EmpID", "1100320"}
}
Dim searchParameters = New Dictionary(Of String, Object) From {
{"Search", search},
{"IncludeAttributes", New String() {"EmpId", "EmpName", "Department", "Salary", "ManagerId"}}
}
Dim jsonSearchParameters = JsonConvert.SerializeObject(searchParameters)
Dim stringContent = New StringContent(jsonSearchParameters, Encoding.UTF8, "application/json")
Alternatively, create a class to hold the parameters:
Public Class Search
Public Property EmpName As String
Public Property EmpID As String
End Class
Public Class SearchParameters
Public Property Search As Search
Public Property IncludeAttributes As String()
End Class
and then fill the classes in with the appropriate data:
Dim search = New Search With
{
.EmpName = "Rachel",
.EmpID = "1100320"
}
Dim searchParameters = New SearchParameters With
{
.Search = search,
.IncludeAttributes = New String() {"EmpId", "EmpName", "Department", "Salary", "ManagerId"}
}
Dim jsonSearchParameters = JsonConvert.SerializeObject(searchParameters)
Dim stringContent = New StringContent(jsonSearchParameters, Encoding.UTF8, "application/json")
As cricket_007 suggested I tried Dictionary of string, object and it worked like a charm. For any one else coming here with the similar issue here is my piece of code, which worked:
Dim searchParameters = New Dictionary(Of String, String)()
searchParameters.Add("EmpId", EmpId)
searchParameters.Add("EmpName", "Rachel")
Dim includeAttributes() As String = {"EmpId", "Name", "Dept", "Manager", "Salary"}
Dim SearchAttributes As New Dictionary(Of String, Object)
SearchAttributes.Add("Search", searchParameters)
SearchAttributes.Add("IncludeAttributes", includeAttributes)
Dim jsonSearchParameters = JsonConvert.SerializeObject(SearchAttributes)

VB JSON without key value

Another JSON query..
I have data in a table which I need to serialize but I do not want to show the key, just the value.. I am currently using this code which gives both key and value..
Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
Dim rows As New List(Of Dictionary(Of String, Object))()
Dim row As Dictionary(Of String, Object)
For Each dr As DataRow In dt.Rows
row = New Dictionary(Of String, Object)()
For Each col As DataColumn In dt.Columns
row.Add(col.ColumnName, dr(col))
Next
rows.Add(row)
Next
Dim X = serializer.Serialize(rows)
Return
Which gives me {"field1" : "data1", "field2" : "data2"},
{"field1" : "data1", "field2" : "data2"},
{"field1" : "data1", "field2" : "data2"}
But I'd like {"data1","data2},{"data1","data2},{"data1","data2}
Can anyone advise..
Thank you in advance..
VB.NET Utility Class to Serialize Deserialize Json String
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Runtime.Serialization.Json
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
''' <summary>
''' JSON Serialization and Deserialization Assistant ClassS
''' </summary>
Public Class JsonHelper
''' <summary>
''' JSON Serialization
''' </summary>
Public Shared Function JsonSerializer(Of T)(ByVal obj As T) As String
Dim ser As New DataContractJsonSerializer(GetType(T))
Dim ms As New MemoryStream()
ser.WriteObject(ms, obj)
Dim jsonString As String = Encoding.UTF8.GetString(ms.ToArray())
ms.Close()
'Replace Json Date String
Dim p As String = "\\/Date\((\d+)\+\d+\)\\/"
Dim matchEvaluator As New MatchEvaluator(AddressOf ConvertJsonDateToDateString)
Dim reg As New Regex(p)
jsonString = reg.Replace(jsonString, matchEvaluator)
Return jsonString
End Function
''' <summary>
''' JSON Deserialization
''' </summary>
Public Shared Function JsonDeserialize(Of T)(ByVal jsonString As String) As T
'Convert "yyyy-MM-dd HH:mm:ss" String as "\/Date(1319266795390+0800)\/"
Dim p As String = "\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}"
Dim matchEvaluator As New MatchEvaluator(AddressOf ConvertDateStringToJsonDate)
Dim reg As New Regex(p)
jsonString = reg.Replace(jsonString, matchEvaluator)
Dim ser As New DataContractJsonSerializer(GetType(T))
Dim ms As New MemoryStream(Encoding.UTF8.GetBytes(jsonString))
Dim obj As T = DirectCast(ser.ReadObject(ms), T)
Return obj
End Function
''' <summary>
''' Convert Serialization Time /Date(1319266795390+0800) as String
''' </summary>
Private Shared Function ConvertJsonDateToDateString(ByVal m As Match) As String
Dim result As String = String.Empty
Dim dt As New DateTime(1970, 1, 1)
dt = dt.AddMilliseconds(Long.Parse(m.Groups(1).Value))
dt = dt.ToLocalTime()
result = dt.ToString("yyyy-MM-dd HH:mm:ss")
Return result
End Function
''' <summary>
''' Convert Date String as Json Time
''' </summary>
Private Shared Function ConvertDateStringToJsonDate(ByVal m As Match) As String
Dim result As String = String.Empty
Dim dt As DateTime = DateTime.Parse(m.Groups(0).Value)
dt = dt.ToUniversalTime()
Dim ts As TimeSpan = dt - DateTime.Parse("1970-01-01")
result = String.Format("\/Date({0}+0800)\/", ts.TotalMilliseconds)
Return result
End Function
End Class
Also
Here is the easiest way to deserialize JSON into an object (using .NET 4):
Dim j As Object = New JavaScriptSerializer().Deserialize(Of Object)(JSONString)
Then, depending on the structure of the new object, you can retrieve the data like so:
r.status = j("status")
r.legs= j("routes")(0)("legs")
and more detailed solution :
I'd recommend you to use JavaScriptSerializer over DataContractJsonSerializer. The reasons are:
JavaScriptSerializer is faster over DataContractJsonSerializer
DataContractJsonSerializer requires more code than JavaScriptSerializer for a simple serialization.
You won't need the DataContract and DataMember attribute to use along with JavaScriptSerializer
Use this data class
<Serializable> _
Public Class ApplicationItem
Public Property application_id() As String
Get
Return m_application_id
End Get
Set
m_application_id = Value
End Set
End Property
Private m_application_id As String
Public Property application_package() As String
Get
Return m_application_package
End Get
Set
m_application_package = Value
End Set
End Property
Private m_application_package As String
End Class
And use this to deserialize your jsonText:
Dim jss As New JavaScriptSerializer()
Dim dict = jss.Deserialize(Of List(Of ApplicationItem))(jsonText)
If you still want to use DataContractJsonSerializer, you can use this code below to deserialize:
Dim obj As New List(Of ApplicationItem)()
Dim ms As New MemoryStream(Encoding.Unicode.GetBytes(json))
Dim serializer As New System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.[GetType]())
obj = DirectCast(serializer.ReadObject(ms), List(Of ApplicationItem))
ms.Close()
ms.Dispose()

Working with nested json file visual basic

i have a nested json file that i want to deserialize, i keep getting an error " Object reference not set to an instance of an object."
here is my json file
[
{
"Name": "Junius",
"LastName": "Lekgwara",
"CellNo": [
{
"CellC": "072685345",
"Voda": "0728589303"
}
]
},
{
"Name": "Phuti",
"LastName": "Gravel",
"CellNo": [
{
"CellC": "08377777777",
"Voda": "089888888888"
}
]
},
{
"Name": "Donald",
"LastName": "Gravel",
"CellNo": [
{
"CellC": "0791408989",
"Voda": "0117689009"
}
]
}
]
here is my Person class
Public Class Person
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _LastName As String
Public Property LastName() As String
Get
Return _LastName
End Get
Set(ByVal value As String)
_LastName = value
End Set
End Property
Public Property cellno As CellNo
End Class
Public Class CellNo
Public Property CellC As String
Public Property Voda As String
End Class
PersonList class
Public Class PersonList
Private _ListPerson As List(Of Person)
Public Property ListPerson() As List(Of Person)
Get
Return _ListPerson
End Get
Set(ByVal value As List(Of Person))
_ListPerson = value
End Set
End Property
Sub New()
_ListPerson = New List(Of Person)
End Sub
End Class
reading json file, when this sub is called i get an error
Public Async Sub LoadFromFile()
Dim reader As String = Await GetFile()
Dim serializer As DataContractJsonSerializer = New DataContractJsonSerializer(GetType(ObservableCollection(Of Person)))
Dim ms As MemoryStream = New MemoryStream(Encoding.UTF8.GetBytes(reader))
Dim listOf As ObservableCollection(Of Person) = New ObservableCollection(Of Person)
listOf = serializer.ReadObject(ms)
For Each item In listOf
list.ListPerson.Add(item)
Debug.WriteLine(item.Name + " " + item.LastName + " " + item.cellno.CellC + " " + item.cellno.Voda) 'Object reference not set to an instance of an object, on item.cellno.CellC and item.cellno.Voda
Next
End Sub
i want to be able to reference it like
Dim person As Person = New Person()
lblName.Text = person.Name
lblLastName.Text = person.LastName
lblCellCNo.Text= person.cellno.CellC
lblCellVodaNo.Text= person.cellno.Voda
how can i fix this?
The JSON shown is a bit different than the class structs you want to use. Person is a List or Array already in the JSON. CellNo is also an array even though it appears in that sample to only have one class object per person.
So, you can skip your PersonList entirely:
Public Class CellNo
Public Property CellC As String
Public Property Voda As String
End Class
Public Class Person
Public Property Name As String
Public Property LastName As String
Public Property CellNo As List(Of CellNo)
End Class
Deserialize to a List(Of Person):
Dim jstr = ... (wherever it comes from)
Dim jp As List(Of Person)
jp = JsonConvert.DeserializeObject(Of List(Of Person))(jstr)
This is now quite usable as is without further manipulations:
For Each P As Person In jp
Console.WriteLine("{0} Cell Voda:{1}", P.Name, P.CellNo(0).Voda)
Next
Junius Cell Voda: 0728589303
Phuti Cell Voda: 089888888888
Donald Cell Voda: 0117689009
Optionally, you can deserialize to an array of Person, and define Person.CellNo as an array also.
i'm not using newtonsoft
You get the same results using NET:
Imports System.Web.Script.Serialization
Dim jss As New JavaScriptSerializer
Dim jp As List(Of Person)
jp = jss.Deserialize(Of List(Of Person))(jstr)
See.. your problem is that
the item List is not well prepared for what you want.
item.cellno HAS CHILD !!!
and
item.cellno.CellC
item.cellno.Voda
must be iterated..
For Each item In listOf
list.ListPerson.Add(item)
'Debug.WriteLine(item.Name + " " + item.LastName + " " + _
'you know that you have just 2 items in : CellNo, and play with that.
For i= 0 to 1
Item.CellNo(i) ' do something with ..
End For
Next
also read this : vb.net datatable Serialize to json
Solved the problem by using CellNo as an array
`"CellNo":[
"072685345",
"0728589303"
]
For Each item In listOf
list.ListPerson.Add(item)
Debug.WriteLine(item.Name + " " + item.LastName)
For Each i In item.CellNo
Debug.WriteLine(i)
Next
Next
display
Junius Lekgwara
Cell No: 072685345
Cell No: 0728589303
Phuti Gravel
Cell No: 08377777777
Cell No: 089888888888
Donald Gravel
Cell No: 0791408989
Cell No: 0117689009