dpskipper dpskipper - 3 months ago 16
Vb.net Question

Error with parsing JSON using Json.Net

I'm using this code to parse my JSON string and it throws an exception, the error is:


An unhandled exception of type 'System.InvalidCastException' occurred in Myapp.exe Additional information: Unable to cast object of type 'Newtonsoft.Json.Linq.JProperty' to type 'Newtonsoft.Json.Linq.JObject'.


I have properly imported Json.Net and this very same code works in a different sub and parses just fine.

Here is my code:

Dim o As JObject = JObject.Parse(responseContent)
Dim results As List(Of JToken) = o.Children().ToList
For Each item As JProperty In results
item.CreateReader()
Select Case item.Name
Case "response"
Dim BatteryCharge As String
For Each subitem As JObject In item.Values
BatteryCharge = subitem("battery_level")
MessageBox.Show(BatteryCharge)
Next
End Select
Next


The JSON string looks like this and for now I only need to fetch
battery_level
however if you could tell me how to include more if I need to that would be great.

{
"response": {
"charging_state": "Complete", // "Charging", ??
"charge_to_max_range": false, // current std/max-range setting
"max_range_charge_counter": 0,
"fast_charger_present": false, // connected to Supercharger?
"battery_range": 239.02, // rated miles
"est_battery_range": 155.79, // range estimated from recent driving
"ideal_battery_range": 275.09, // ideal miles
"battery_level": 91, // integer charge percentage
"battery_current": -0.6, // current flowing into battery
"charge_starting_range": null,
"charge_starting_soc": null,
"charger_voltage": 0, // only has value while charging
"charger_pilot_current": 40, // max current allowed by charger & adapter
"charger_actual_current": 0, // current actually being drawn
"charger_power": 0, // kW (rounded down) of charger
"time_to_full_charge": null, // valid only while charging
"charge_rate": -1.0, // float mi/hr charging or -1 if not charging
"charge_port_door_open": true
}
}

Answer

The easiest way is to avoid using JObject.Parse approach and to instead deserialize it to a POCO, like so:

Sub Main
    Dim response = JsonConvert.DeserializeObject(Of ResponseObject)("*your JSON string goes here*")

    Console.WriteLine("The battery level is " & response.response.battery_level)
End Sub

Public Class Response
    Public Property charging_state As String
    Public Property charge_to_max_range As Boolean
    Public Property max_range_charge_counter As Integer
    Public Property fast_charger_present As Boolean
    Public Property battery_range As Double
    Public Property est_battery_range As Double
    Public Property ideal_battery_range As Double
    Public Property battery_level As Integer
    Public Property battery_current As Double
    Public Property charge_starting_range As Object
    Public Property charge_starting_soc As Object
    Public Property charger_voltage As Integer
    Public Property charger_pilot_current As Integer
    Public Property charger_actual_current As Integer
    Public Property charger_power As Integer
    Public Property time_to_full_charge As Object
    Public Property charge_rate As Double
    Public Property charge_port_door_open As Boolean
End Class

Public Class ResponseObject
    Public Property response As Response
End Class

This also means that you can access and use the other properties later on in addition to battery_level.