Click here to Skip to main content
15,670,482 members
Please Sign up or sign in to vote.
1.80/5 (2 votes)
See more:
I am trying to use Newtonsoft JSon to deserialize to my class, but receives an error:
Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.dll
Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in System.Private.CoreLib.dll

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'PassatRep.LocIQRoot' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.'

Debug returns the following

[{"place_id":"83003376","licence":"\u00a9 CC BY 4.0, Data \u00a9 OpenStreetMap contributors, ODbL 1.0","osm_type":"way","osm_id":"27462943","boundingbox":["55.3283734","55.3284947","8.7620641","8.7623819"]{"lat":"55.3283734","lon":"8.7620641","display_name":"Torvet, Ribe, Esbjerg Municipality, Region of Southern Denmark, 6760, Denmark","class":"highway","type":"pedestrian","importance":0.31}]

Here is a link to the website where the Json response is located

What is wrong with the Json response?
Thank you in advance

Here is my class

<pre>Public Class LocationIQ
    Public Shared Async Function GetLocationIQ(ByVal SearchFor As String) As Task(Of LocIQRoot) 
        Dim httpn = New HttpClient()

        Dim url As String = "" & Keys.LocationIQKey & "&q=" & SearchFor & "&format=json"
 Dim response As HttpResponseMessage = Await httpn.GetAsync(url)
        Dim result = Await response.Content.ReadAsStringAsync()


        Dim data As LocIQRoot = JsonConvert.DeserializeObject(Of LocIQRoot)(result)
        Return data
    End Function
End Class

Public Class LocIQRoot
    Public Property Loc() As LocIQ
End Class

Public Class LocIQ
    Public Property place_id As String
    Public Property licence As String
    Public Property osm_type As String
    Public Property osm_id As String
    Public Property boundingbox As List(Of String)
    Public Property lat As String
    Public Property lon As String
    Public Property display_name As String
    Public Property IQclass As String
    Public Property type As String
    Public Property importance As Double
    Public Property icon As String
End Class

    Private Async Sub btnTest3_Click(sender As Object, e As RoutedEventArgs) Handles btnTest3.Click
        Dim aa As LocIQRoot = Await LocationIQ.GetLocationIQ("Torvet 1 28 ribe")
    End Sub

What I have tried:

I have tried to fix this error, but I think it has something to with the way this Json response is presented
Updated 8-Nov-18 2:23am

1 solution

Because you are trying to make the library do something that it is not intended to do; it is illegal and not safe to convert the values from the type specified, array, to the type that you require, object.

In almost every language, an array is a collection of elements of the same type. Even in the JavaScript realm, you would create an array and put in the same objects in the container and then you serialize the array, pass it over to another computer over the network, or leave it there as an evidence to future alien race, once the data is to be read from string to an object, you need to make sure you are parsing the object to the correct representation. In JavaScript, you can easily tell whether string data is an array or an object representation, the first character being [ means an array, and { meaning an object. Otherwise they are mostly invalid.

But here comes the problem. You are trying to now read the data that is array, but you are trying to parse it as an object. You are telling the library to parse an object, and are providing it with data that is for an array.

To fix it, just pass the list interface as the type parameter, maybe this,
' I am no VB.NET expert
Dim data As List(Of LocIQRoot) = JsonConvert.DeserializeObject(Of List(Of LocIQRoot))(result)
This will parse the data as a List, and you can then read the objects in a quick foreach loop.

Also, I wrote an article on this topic that you can check out, From zero to hero in JSON with C#[^]. I explores some cases and scenarios, and you can find some more tips and hints in the QA section under the article.
Share this answer
N. Henrik Lauridsen 8-Nov-18 10:37am    
Hi Afzaal, thanks a lot. That did it and thank you for your explanation. You are after all a VB.Net expert :)
Afzaal Ahmad Zeeshan 8-Nov-18 11:14am    
Thank you, Henrik!
Member 14209396 2-Apr-19 9:34am    
Thank you Afzaal - this was exactly what I needed! Here's the C# version of your solution just in case anyone is interested :)

IList<lociqroot> data = JsonConvert.DeserializeObject(List<lociqroot>))(result);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900