Max Headroom
Max Headroom

Reputation: 141

Exception when parsing a JSON as a Json Object

I’m hoping that someone can help me to work out where I am going wrong with this.
I have a simple JSON file, here is a condensed version of it.

[
  {
    "LocationGuid":"c35e549f-ffb8-4828-8290-d66c2f9b735f",
    "Name":"Volkswagen",
    "FolderPath":"C:\\temp\\Volkswagen"
  },
  {
    "LocationGuid":"814e7584-9f99-40a6-8520-3f5d467ea8d9",
    "Name":"Nissan",
    "FolderPath":"C:\\temp\\Nissan"
  },
  {
    "LocationGuid":"51d60458-01ac-421d-8fb8-3663f5963fbf",
    "Name":"Ford",
    "FolderPath":"C:\\temp\\Ford"
  }
]

I want to separate the data into rows.
The following code compiles...

Private Sub UpdateExMailLocations(sPath As String)
    Dim sLocationGUID As String
    Dim sName As String
    Dim sFolderPath As String

    '' Retrieve the whole JSON file
    Dim rawJSON = File.ReadAllText(sPath)

    '' Parse it into JSON items
    Dim jsonObject As JObject = JObject.Parse(rawJSON)
    Dim jsonArray As JArray = jsonObject("result")

    For Each item As JObject In jsonArray
        sLocationGUID = item.SelectToken("LocationGUID").ToString
        sName = item.SelectToken("Name").ToString
        sFolderPath = item.SelectToken("FolderPath").ToString
        MsgBox("Record = " & sLocationGUID & "," & sName & "," & sFolderPath)
    Next
End Sub

When it reaches the statement:

Dim jsonObject As JObject = JObject.Parse(rawJSON)

It throws the following exception:

Newtonsoft.Json.JsonReaderException: 'Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.'

I am a complete novice so you may have to spell out the solution in simple terms :-)

Upvotes: 2

Views: 640

Answers (1)

Jimi
Jimi

Reputation: 32278

You JSON is enclosed in square brackets ([ ... ]), so its structure represents and array of objects, not a single object. The array contains objects that have three properties: two of Type String, one can be parsed directly as a Guid.

You could use JArray.Parse() to parse that JSON:

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

Dim locArray = JArray.Parse(rawJSON)

For Each loc As JObject In locArray
    Console.WriteLine(loc("LocationGuid"))
    Console.WriteLine(loc("Name"))
    Console.WriteLine(loc("FolderPath"))
Next

Or build a simple class Model that describes the JSON object, then deserialize to a List (Of Class) or an array, then handle this collection as usual.

This form is often used since it allows to use .Net properties without manually writing JSON property names as strings.
You don't need to go back to the JSON to find the property you're looking for, possibly nested, in more complex structures and can avoid typing or interpretation errors.

There are on-line free services that convert a JSON to .Net classes, as JSON Utils (includes VB.Net as language) and JSON validators/formatters as JSON Formatter and Validator.

Public Class LocationData
    Public Property LocationGuid As Guid
    Public Property Name As String
    Public Property FolderPath As String
End Class

' [...]

' Deserialize to a List(Of class) objects  
Dim locationsData = JsonConvert.DeserializeObject(Of List(Of LocationData))(rawJSON)
' Or as an array of objects:  
' Dim locationsData = JsonConvert.DeserializeObject(Of LocationData())(rawJSON)

For Each loc As LocationData In locationsData
    Console.WriteLine(loc.LocationGuid)
    Console.WriteLine(loc.Name)
    Console.WriteLine(loc.FolderPath)
Next

Upvotes: 1

Related Questions