שתף באמצעות


read JSON file

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.

StackOverFlow


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.

StackOverFlow


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.

StackOverFlow


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.

StackOverFlow