N. Henrik Lauridsen Ответов: 1

Ошибка десериализации Newtonsoft json


Hi,
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 LocationIQ.com 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) 
        Debug.WriteLine(Keys.LocationIQKey)
        Dim httpn = New HttpClient()

        Dim url As String = "https://eu1.locationiq.com/v1/search.php?key=" & Keys.LocationIQKey & "&q=" & SearchFor & "&format=json"
        
 Dim response As HttpResponseMessage = Await httpn.GetAsync(url)
        Dim result = Await response.Content.ReadAsStringAsync()

        Debug.WriteLine(result)

        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
    ' https://locationiq.com/docs#forward-geocoding
    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


Что я уже пробовал:

I have tried to fix this error, but I think it has something to with the way this Json response is presented

1 Ответов

Рейтинг:
12

Afzaal Ahmad Zeeshan

Потому что вы пытаетесь заставить библиотеку делать то, что она не предназначена делать; это незаконно и небезопасно преобразовывать значения из указанного типа, массива, в тип, который вам требуется, объект.

Почти в каждом языке массив представляет собой набор элементов одного и того же типа. Даже в области JavaScript вы создаете массив и помещаете те же объекты в контейнер, а затем сериализуете массив, передаете его на другой компьютер по сети или оставляете его там в качестве доказательства будущей инопланетной расы. как только данные будут считаны из строки в объект, вам нужно убедиться, что вы анализируете объект в правильном представлении. В JavaScript вы можете легко определить, являются ли строковые данные массивом или представлением объекта, причем первым символом является [ означает массив, а также { имеется в виду объект. В противном случае они есть в основном недействительный.

Но тут возникает проблема. Теперь вы пытаетесь прочитать данные, которые являются массивом, но вы пытаетесь разобрать их как объект. Вы приказываете библиотеке проанализировать объект и предоставляете ей данные, предназначенные для массива.

Чтобы исправить это, просто передайте интерфейс списка в качестве параметра типа, возможно, это,

' I am no VB.NET expert
Dim data As List(Of LocIQRoot) = JsonConvert.DeserializeObject(Of List(Of LocIQRoot))(result)
Это позволит проанализировать данные в виде списка, а затем вы сможете быстро прочитать объекты. foreach петля.

Кроме того, я написал статью на эту тему, которую вы можете проверить, От нуля до героя в JSON с C#[^Я исследую некоторые случаи и сценарии, и вы можете найти еще несколько советов и подсказок в разделе QA под этой статьей.


N. Henrik Lauridsen

Привет Afzaal, спасибо большое. Вот и все, и спасибо вам за объяснение. В конце концов, вы-VB.Чистый эксперт :)

Afzaal Ahmad Zeeshan

Спасибо тебе, Хенрик!

Member 14209396

Спасибо Afzaal - это было именно то, что мне нужно! Вот версия вашего решения на C# на всякий случай, если кому-то это интересно :)

IList<lociqroot> data = JsonConvert.DeserializeObject(List<lociqroot>))(результат);