הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
Question
Monday, March 11, 2019 7:52 PM
Good Evening,
I'm trying to read a JSON file in VB.net,
the results is not complete.
this is the JSON example:
{
"Passes":
{
"Areas":
[
{
"id":28646,
"PassTimes":
[
{
"gap":-1,
"from":22343.766438359,
"to":22343.7664384495,
"UTCfrom":"04.03.2019 18:23:40",
"UTCto":"04.03.2019 18:23:40",
"rms":9.04219632502645E-8
}
]
}
]
}
,
{
"id":33412,
"PassTimes":
[
{
"gap":-1,
"from":22343.145140881,
"to":22343.1451409714,
"UTCfrom":"04.03.2019 3:29:00",
"UTCto":"04.03.2019 3:29:00",
"rms":9.04256012290716E-8
}
]
}
]
}
}
And this is my code:
Imports System.IO
Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim STR As StreamReader
STR = New StreamReader(filename.json")
Dim rawresp As String
rawresp = STR.ReadToEnd()
Dim jo = Newtonsoft.Json.Linq.JObject.Parse(rawresp)
Dim VidID1 = jo("Passes")("Areas")(0)("id")
Dim VidID2 = jo("Passes")("Areas")(0)("PassTimes")(0)("UTCfrom")
Dim VidID3 = jo("Passes")("Areas")(0)("PassTimes")(0)("UTCto")
ListBox1.Items.Add(VidID1)
ListBox1.Items.Add(VidID2)
ListBox1.Items.Add(VidID3)
the only output i get is the first values:
"id":28646,
"UTCfrom":"04.03.2019 18:23:40",
"UTCto":"04.03.2019 18:23:40",And in case of using array i get an error,For Each item As JObject In array"The error is : Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObjectPlease, i need your advise and help,Thanks,Khaled
All replies (13)
Monday, March 11, 2019 9:34 PM
If your Json is always in the same format you can use the following link to create classes that will encapsulate the JSon (the link says C# but you can follow the steps to create VB Classes).
https://www.c-sharpcorner.com/UploadFile/pranayamr/generate-class-from-json-xml-in-visual-studio/
The example you want to see is :
Approach 2: Automated using Visual Studio
Lloyd Sheen
Tuesday, March 12, 2019 3:27 AM
Hi,
here a console demo as an excitation:
Imports Newtonsoft.Json
Imports System.IO
Module Module07
Sub Main()
Try
Dim c As New Demo
c.Execute()
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
Console.WriteLine("Continue enter key")
Console.ReadKey()
End Sub
Friend Class Demo
Friend Sub Execute()
Dim inpName = "Module07Json.txt"
Dim inp = ReadFromJsonFile(Of Rootobject)(inpName)
Console.WriteLine(inp)
Console.WriteLine(inp.Passes)
For Each a As Area In inp.Passes.Areas
Console.WriteLine(a)
Console.WriteLine($" id: {a.id}")
Console.WriteLine($" {a.PassTimes}")
For Each pt As Passtime In a.PassTimes
Console.WriteLine($" {pt}")
Console.WriteLine($" from: {pt.from}")
Console.WriteLine($" to: {pt.To}")
Console.WriteLine($" gap: {pt.gap}")
Console.WriteLine($" rms: {pt.rms}")
Console.WriteLine($" UTCFrom: {pt.UTCfrom}")
Console.WriteLine($" UTCTo: {pt.UTCto}")
Next
Next
End Sub
Public Shared Function ReadFromJsonFile(Of T As New)(filePath As String) As T
Using reader As New StreamReader(filePath)
Dim fileContents = reader.ReadToEnd()
Return JsonConvert.DeserializeObject(Of T)(fileContents)
End Using
End Function
Public Shared Sub WriteToJsonFile(Of T As New)(filePath As String, objectToWrite As T, Optional append As Boolean = False)
Dim contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite)
Using writer As New StreamWriter(filePath, append)
writer.Write(contentsToWriteToFile)
End Using
End Sub
Public Class Rootobject
Public Property Passes As Pass
End Class
Public Class Pass
Public Property Areas As Area()
End Class
Public Class Area
Public Property id As Integer
Public Property PassTimes As Passtime()
End Class
Public Class Passtime
Public Property gap As Integer
Public Property from As Double
Public Property [To] As Double
Public Property UTCfrom As String
Public Property UTCto As String
Public Property rms As Double
End Class
End Class
End Module
and the json file (Module07Json.txt):
{
"Passes":
{
"Areas":
[
{
"id":28646,
"PassTimes":
[
{
"gap":-1,
"from":22343.766438359,
"to":22343.7664384495,
"UTCfrom":"04.03.2019 18:23:40",
"UTCto":"04.03.2019 18:23:40",
"rms":9.04219632502645E-8
}
]
}
,
{
"id":33412,
"PassTimes":
[
{
"gap":-1,
"from":22343.145140881,
"to":22343.1451409714,
"UTCfrom":"04.03.2019 3:29:00",
"UTCto":"04.03.2019 3:29:00",
"rms":9.04256012290716E-8
}
]
}
]
}
}
and the displayed result:
ConsoleApp1.Program03+Rootobject
ConsoleApp1.Program03+Passes
ConsoleApp1.Program03+Area
id: 28646
ConsoleApp1.Program03+Passtime[]
ConsoleApp1.Program03+Passtime
from: 22343,77
to: 22343,77
gap: -1
rms: 9,042196E-08
UTCFrom: 04.03.2019 18:23:40
UTCTo: 04.03.2019 18:23:40
ConsoleApp1.Program03+Area
id: 33412
ConsoleApp1.Program03+Passtime[]
ConsoleApp1.Program03+Passtime
from: 22343,14
to: 22343,14
gap: -1
rms: 9,04256E-08
UTCFrom: 04.03.2019 3:29:00
UTCTo: 04.03.2019 3:29:00
Continue enter key
--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Tuesday, March 12, 2019 6:03 AM
thank you for your useful idea,
After pasting and creating the JSON file , how can i write the specific objects in a LISTBOX?
Tuesday, March 12, 2019 6:03 AM
Thank you for your great effort, i will try using this method
Tuesday, March 12, 2019 10:34 AM
Hi,
here a console demo as an excitation:using Newtonsoft.Json; using System; using System.IO; namespace ConsoleApp1 { class Program03 { static void Main(string[] args) { try { Demo c = new Demo(); c.Execute(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.WriteLine("Continue enter key"); Console.ReadKey(); } class Demo { internal void Execute() { string inpName = "Program03Json.txt"; var inp = ReadFromJsonFile<Rootobject>(inpName); Console.WriteLine(inp); Console.WriteLine(inp.Passes); foreach (var a in inp.Passes.Areas) { Console.WriteLine(a); Console.WriteLine($" id: {a.id}"); Console.WriteLine($" {a.PassTimes}"); foreach (var pt in a.PassTimes) { Console.WriteLine($" {pt}"); Console.WriteLine($" from: {pt.from}"); Console.WriteLine($" to: {pt.to}"); Console.WriteLine($" gap: {pt.gap}"); Console.WriteLine($" rms: {pt.rms}"); Console.WriteLine($" UTCFrom: {pt.UTCfrom}"); Console.WriteLine($" UTCTo: {pt.UTCto}"); } } } } public static T ReadFromJsonFile<T>(string filePath) where T : new() { using (TextReader reader = new StreamReader(filePath)) { var fileContents = reader.ReadToEnd(); return JsonConvert.DeserializeObject<T>(fileContents); } } public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new() { var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite); using (TextWriter writer = new StreamWriter(filePath, append)) writer.Write(contentsToWriteToFile); } public class Rootobject { public Passes Passes { get; set; } } public class Passes { public Area[] Areas { get; set; } } public class Area { public int id { get; set; } public Passtime[] PassTimes { get; set; } } public class Passtime { public int gap { get; set; } public float from { get; set; } public float to { get; set; } public string UTCfrom { get; set; } public string UTCto { get; set; } public float rms { get; set; } } } }
and the json file:
{ "Passes": { "Areas": [ { "id":28646, "PassTimes": [ { "gap":-1, "from":22343.766438359, "to":22343.7664384495, "UTCfrom":"04.03.2019 18:23:40", "UTCto":"04.03.2019 18:23:40", "rms":9.04219632502645E-8 } ] } , { "id":33412, "PassTimes": [ { "gap":-1, "from":22343.145140881, "to":22343.1451409714, "UTCfrom":"04.03.2019 3:29:00", "UTCto":"04.03.2019 3:29:00", "rms":9.04256012290716E-8 } ] } ] } }
and the displayed result:
ConsoleApp1.Program03+Rootobject
ConsoleApp1.Program03+Passes
ConsoleApp1.Program03+Area
id: 28646
ConsoleApp1.Program03+Passtime[]
ConsoleApp1.Program03+Passtime
from: 22343,77
to: 22343,77
gap: -1
rms: 9,042196E-08
UTCFrom: 04.03.2019 18:23:40
UTCTo: 04.03.2019 18:23:40
ConsoleApp1.Program03+Area
id: 33412
ConsoleApp1.Program03+Passtime[]
ConsoleApp1.Program03+Passtime
from: 22343,14
to: 22343,14
gap: -1
rms: 9,04256E-08
UTCFrom: 04.03.2019 3:29:00
UTCTo: 04.03.2019 3:29:00
Continue enter key--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Peter, please edit this code and post in VB.NET as this is a VB.NET forum, we don't expect those asking questions here to know how to convert C# to VB.NET.
Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
NuGet BaseConnectionLibrary for database connections.
Tuesday, March 12, 2019 12:40 PM
Thank you Karen for your reply,
I get an error (An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize JSON array into type 'WindowsApplication1.Form1+Satellitestable')
This error occured at the line :
Return JsonConvert.DeserializeObject(Of T)(fileContents)
Any advise??
Tuesday, March 12, 2019 1:20 PM
Hi Karen,
thanks for the correction. I edit my post.
--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Tuesday, March 12, 2019 1:30 PM
Hello,
I took your json, placed it in a string (this is just bypassing reading from a file).
Public Class Form1
Private jsonData As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
jsonData = <Data>
{
"Passes":{
"Areas":[
{
"id":28646,
"PassTimes":[
{
"gap":-1,
"from":22343.766438359,
"to":22343.7664384495,
"UTCfrom":"04.03.2019 18:23:40",
"UTCto":"04.03.2019 18:23:40",
"rms":9.04219632502645E-8
}
]
},
{
"id":33412,
"PassTimes":[
{
"gap":-1,
"from":22343.145140881,
"to":22343.1451409714,
"UTCfrom":"04.03.2019 3:29:00",
"UTCto":"04.03.2019 3:29:00",
"rms":9.04256012290716E-8
}
]
}
]
}
}
</Data>.Value
End Sub
Created classes using Visual Studio paste as classes.
Public Class Rootobject
Public Property Passes As Passes
End Class
Public Class Passes
Public Property Areas() As Area
End Class
Public Class Area
Public Property id As Integer
Public Property PassTimes() As Passtime
End Class
Public Class Passtime
Public Property gap As Integer
Public Property from As Single
Public Property _to As Single
Public Property UTCfrom As String
Public Property UTCto As String
Public Property rms As Single
End Class
Then in a button click event copied in your code.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim jo = Newtonsoft.Json.Linq.JObject.Parse(jsonData)
Dim VidID1 = jo("Passes")("Areas")(0)("id")
Dim VidID2 = jo("Passes")("Areas")(0)("PassTimes")(0)("UTCfrom")
Dim VidID3 = jo("Passes")("Areas")(0)("PassTimes")(0)("UTCto")
End Sub
Results (set a breakpoint) from running the code above/
Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
NuGet BaseConnectionLibrary for database connections.
Tuesday, March 12, 2019 1:31 PM
Hi,
if you get the exception "Cannot deserialize" your json string/stream and your object model (classes) do not match.
--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Tuesday, March 12, 2019 1:43 PM
Hi Karen,
thanks for the correction. Ich edit my post.--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Thank you Peter :-)
Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
NuGet BaseConnectionLibrary for database connections.
Tuesday, March 12, 2019 1:48 PM
Thank you karen,
It works but gives only the first object, not all
How to make a loop in this case to get all repeated data?
Tuesday, March 12, 2019 1:57 PM
HI,
see my post:
Dim inp = ReadFromJsonFile(Of Rootobject)(inpName)
For Each a As Area In inp.Passes.Areas
' all Areas
For Each pt As Passtime In a.PassTimes
' all PassTimes
Next
Next
--
Viele Grüsse / Best Regards
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks
Wednesday, March 13, 2019 10:22 AM
Hello,
To go deeper here is an example that has the same mocked data along with several methods to access the json data e.g. GetRootObject, GetAreas, GetArea (by identifier). So this may appear a bit drawn out but that is dependent on your needs.
Concrete classes
Public Class Rootobject
Public Property Passes As Pass
End Class
Public Class Pass
Public Property Areas As Area()
End Class
Public Class Area
Public Property id As Integer
Public Property PassTimes As Passtime()
End Class
Public Class Passtime
Public Property gap As Integer
Public Property from As Double
Public Property [To] As Double
Public Property UTCfrom As String
Public Property UTCto As String
Public Property rms As Double
End Class
Class to get json
Imports Newtonsoft.Json
Public Class Operations
Public Function GetMockedUpJson() As String
Dim jsonData = <Data>
{
"Passes":
{
"Areas":
[
{
"id":28646,
"PassTimes":
[
{
"gap":-1,
"from":22343.766438359,
"to":22343.7664384495,
"UTCfrom":"04.03.2019 18:23:40",
"UTCto":"04.03.2019 18:23:40",
"rms":9.04219632502645E-8
}
]
}
,
{
"id":33412,
"PassTimes":
[
{
"gap":-1,
"from":22343.145140881,
"to":22343.1451409714,
"UTCfrom":"04.03.2019 3:29:00",
"UTCto":"04.03.2019 3:29:00",
"rms":9.04256012290716E-8
}
]
}
]
}
}
</Data>.Value
Return jsonData
End Function
''' <summary>
''' Get root
''' </summary>
''' <returns></returns>
Public Function GetRootObject() As Rootobject
Return JsonConvert.DeserializeObject(Of Rootobject)(GetMockedUpJson())
End Function
''' <summary>
''' Get area
''' </summary>
''' <returns></returns>
Public Function GetAreas() As List(Of Area)
Return GetRootObject().Passes.Areas.ToList()
End Function
''' <summary>
''' Get area by id
''' </summary>
''' <param name="identifier"></param>
''' <returns></returns>
Public Function GetArea(identifier As Integer) As Area
Return GetAreas().FirstOrDefault(Function(item) item.id = identifier)
End Function
''' <summary>
''' Simple example for iterating
''' </summary>
Public Sub Demo()
GetAreas().ForEach(
Sub(item)
Console.WriteLine($"Id: {item.id}")
item.PassTimes.ToList().ForEach(
Sub(passtime)
Console.WriteLine($" Gap: {passtime.gap} From: {passtime.from}")
End Sub)
End Sub)
End Sub
End Class
Form code
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ops As New Operations
ops.Demo()
Dim areaIdentifier As Integer = 33412
Dim area = ops.GetArea(areaIdentifier)
If area IsNot Nothing Then
If area.PassTimes.FirstOrDefault() IsNot Nothing Then
MessageBox.Show(area.PassTimes(0).UTCfrom)
End If
End If
End Sub
End Class
Iteration results
Id: 28646
Gap: -1 From: 22343.766438359
Id: 33412
Gap: -1 From: 22343.145140881
Get area by id
Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
NuGet BaseConnectionLibrary for database connections.