I always get the error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Test.Form15+results[]]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'result', line 1, position 10.
My code is as follows and i'm not sure if it's the double-quotes causing the issues, or the bracket at the start of the json string. Any tips would be appreciated.
Public Class Form15
Public Class UTicketContact
<JsonProperty("display_value")>
Public Property DisplayValue As String
<JsonProperty("link")>
Public Property Link As String
End Class
Public Class URequestedFor
<JsonProperty("display_value")>
Public Property DisplayValue As String
<JsonProperty("link")>
Public Property Link As String
End Class
Public Class AssignedTo
<JsonProperty("display_value")>
Public Property DisplayValue As String
<JsonProperty("link")>
Public Property Link As String
End Class
Public Class OpenedBy
<JsonProperty("display_value")>
Public Property DisplayValue As String
<JsonProperty("link")>
Public Property Link As String
End Class
Public Class AssignmentGroup
<JsonProperty("display_value")>
Public Property DisplayValue As String
<JsonProperty("link")>
Public Property Link As String
End Class
Public Class Result
<JsonProperty("u_ticket_contact")>
Public Property UTicketContact As UTicketContact
<JsonProperty("u_requested_for")>
Public Property URequestedFor As URequestedFor
<JsonProperty("assigned_to")>
Public Property AssignedTo As AssignedTo
<JsonProperty("opened_by")>
Public Property OpenedBy As OpenedBy
<JsonProperty("assignment_group")>
Public Property AssignmentGroup As AssignmentGroup
End Class
Public Class results
<JsonProperty("result")>
Public Property Result As Result()
End Class
Function FindRequestedFor(ByVal instancename As String,
ByVal rtask As String) As String
Dim requestedfor As String = ""
'Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
Dim accessToken As String = GenerateToken("instancenameredacted",
"clientIdredacted",
"clientSecretredacted",
"accountredacted",
"accountpasswordredacted")
Dim url As String = "https://" & instancename & ".service-now.com/api/ubis2/request/rtask?query=number%3D" & rtask
Dim request As WebRequest = WebRequest.Create(url)
Dim dataStream As Stream
request.ContentType = "application/json; charset=utf-8"
request.Method = "GET"
request.Headers.Add("Authorization", "Bearer " & accessToken)
dataStream = request.GetResponse.GetResponseStream
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd
'Format of the JSON string is: ""{
""result"": [
{
""u_ticket_contact"": {
""display_value"": ""Name1"",
""link"": ""https://instance.service-now.com/api/now/table/sys_user/470104cf600ad400808370bee6ad2596""
},
""u_requested_for"": {
""display_value"": ""Name2"",
""link"": ""https://instance.service-now.com/api/now/table/sys_user/470104cf600ad400808370bee6ad2596""
},
""assigned_to"": {
""display_value"": ""Name3"",
""link"": ""https://instance.service-now.com/api/now/table/sys_user/98c7a3e5ac723040773cf2044a10de0c""
},
""opened_by"": {
""display_value"": ""Name4"",
""link"": ""https://instance.service-now.com/api/now/table/sys_user/470104cf600ad400808370bee6ad2596""
},
""assignment_group"": {
""display_value"": ""Group Name1"",
""link"": ""https://instance.service-now.com/api/now/table/sys_user_group/bad979fa19c44a40b5a0d99e2b982e75""
}
}
]
}""
Console.WriteLine(responseFromServer)
reader.Close()
dataStream.Close()
Dim test = JsonConvert.DeserializeObject(Of List(Of results()))(responseFromServer)
End Function
end class
I would use List(Of Result) type with initialization as below:
Public Class results
<JsonProperty("result")>
Public Property Result As New List(Of Result)
End Class
Related
So I have an HTTP response that gives me this data:
{
"result":"success",
"records":{
"509442013":{
"nif":509442013,
"seo_url":"nexperience-lda",
"title":"Nexperience Lda",
"address":"Rua da Lionesa Nº 446, Edifício G20",
"pc4":"4465",
"pc3":"671",
"city":"Leça do Balio",
"activity":"Desenvolvimento de software. Consultoria em informática. Comércio de equipamentos e sistemas informáticos. Exploração de portais web.",
"status":"active",
"cae":"62010",
"contacts":{
"email":"info#nex.pt",
"phone":"220198228",
"website":"www.nex.pt",
"fax":"224 905 459"
},
"structure":{
"nature":"LDA",
"capital":"5000.00",
"capital_currency":"EUR"
},
"geo":{
"region":"Porto",
"county":"Matosinhos",
"parish":"Leça do Balio"
},
"place":{
"address":"Rua da Lionesa Nº 446, Edifício G20",
"pc4":"4465",
"pc3":"671",
"city":"Leça do Balio"
},
"racius":"http://www.racius.com/nexperience-lda/",
"alias":"Nex - Nexperience, Lda",
"portugalio":"http://www.portugalio.com/nex/"
}
},
"nif_validation":true,
"is_nif":true,
"credits":{
"used":"free",
"left":[
]
}
}
And I need to extract some data from it, like the fields:
NIF
title
and the email and phone that are inside the contacts array.
I need the data to populate some TextBoxes in my Form.
To get the http response I have this button but I don't know how to extract the data I need.
Can someone help me?
My code:
Private Sub Btn_NIFImport_Click(sender As Object, e As EventArgs) Handles Btn_NIFImport.Click
Dim key As String = "xxxxxxxxxxxxxxxxxxxxxxxxxx"
Try
'Create the request
Dim request As HttpWebRequest = HttpWebRequest.Create("http://www.nif.pt/?json=1&q=" & Txt_NIFImport.Text & "&key=" & key)
request.Proxy = Nothing
request.UserAgent = "Test"
'Create the response reader
Dim response As HttpWebResponse = request.GetResponse
Dim responseStream As System.IO.Stream = response.GetResponseStream
'Create a new stream reader
Dim streamReader As New System.IO.StreamReader(responseStream)
Dim data As String = streamReader.ReadToEnd
streamReader.Close()
'Display the data on the screen
Txt_Teste.Text = data
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Thanks in advance.
after you get the response from the http request you need to deserialize the json to an object in vb.net
To Classes to create the object by your json:
Public Class [Structure]
Public Property nature As String
Public Property capital As String
Public Property capital_currency As String
End Class
Public Class Geo
Public Property region As String
Public Property county As String
Public Property parish As String
End Class
Public Class Place
Public Property address As String
Public Property pc4 As String
Public Property pc3 As String
Public Property city As String
End Class
Public Class Record
Public Property nif As Integer
Public Property seo_url As String
Public Property title As String
Public Property address As String
Public Property pc4 As String
Public Property pc3 As String
Public Property city As String
Public Property activity As String
Public Property status As String
Public Property cae As String
Public Property contacts As Contacts
Public Property [structure] As [Structure]
Public Property geo As Geo
Public Property place As Place
Public Property racius As String
Public Property [alias] As String
Public Property portugalio As String
End Class
Public Class Credits
Public Property used As String
Public Property left As List(Of Object)
End Class
Public Class Root
Public Property result As String
Public Property records As Dictionary(Of String, Record)
Public Property nif_validation As Boolean
Public Property is_nif As Boolean
Public Property credits As Credits
End Class
and to deserialize added after you get the response the following line:
Root l = JsonConvert.DeserializeObject<Root>(response);
EDIT:
I made some changes in the code so now you use with Dictionary that has KEY in your json '509442013' and value As Record (Notice that I change the class name as was before '_509442013')
And in the root changes
Public Property records As Dictionary(Of String, Record)
now this will work in each time even if you will get in each http request ID as class that not the same.
notice that the only way you can get the value is by the KEY you already pass in the http request.
Added GIF:
(In my case I change the ID and city, in the result show the city from the json)
Convert Button:
Dim jsonString As String = tbInput.Text
Dim l As Root = JsonConvert.DeserializeObject(Of Root)(jsonString)
tbResult.Text = l.records(tbKEY.Text.ToString).city.ToString()
tbKEY get the value from the screen like in my gif example.
I want to deserialize a json file into 'Artikelstammdaten' and afterwards to a list of 'Artikelstammdaten' (don't know how to iterate over the deserialized json yet). I already tried to deserialize it into the Rootobject, but the object was also "Nothing"Here is what i have tried:
If OpenfilePath IsNot Nothing Then
Dim asd As Artikelstammdaten
Dim fileReader As StreamReader
fileReader = My.Computer.FileSystem.OpenTextFileReader(OpenfilePath)
asd = JsonConvert.DeserializeObject(Of Artikelstammdaten)(fileReader.ReadToEnd)
End If
Edit: This is what the class structure looks like now:
Public Class Artikelstammdaten
Public Property Artikel As String
Public Property BezeichnungDE As String
Public Property BezeichnungEN As String
Public Property Einheit As String
Public Property MatGrp As String
Public Property Kostenart As Integer?
Public Property Vertriebstext_DE As String
Public Property Vertriebstext_EN As String
Public Property Stueckliste As String
Public Property Status As String
Public Property Klasse As String
Public Property Mantelflaeche As Double?
Public Property Gewicht As Integer?
Public Property KlasseID As String
End Class
Public Class Stueckliste
Public Property Verkaufsartikel As String
Public Property Position As Integer?
Public Property PosArtikel As String
Public Property PosBezeichnung As String
Public Property PosKostenart As Integer?
Public Property Datum As String
Public Property Material As Double?
Public Property GMK As Double?
Public Property Lohn As Double?
Public Property Menge As Integer?
Public Property Mengeneinheit As String
End Class
Public Class Arbeitsgaenge
Public Property Verkaufsartikel As String
Public Property AGNR As Integer?
Public Property Bereich As String
Public Property Lohn As Double?
Public Property Kostenstelle As Integer?
Public Property ARBPLATZ As String
End Class
Public Class RootObject
Public Property Artikelstammdaten As List(Of Artikelstammdaten)
Public Property Stueckliste As List(Of Stueckliste)
Public Property Arbeitsgaenge As List(Of Arbeitsgaenge)
End Class
Edit: I also changed the names from "ManufacturingCosts" and "MaterialCosts" to "Stueckliste" and "Arbeitsgaenge"
And here is my json-File:
{"Artikelstammdaten":[{"Artikel":"VAUBEF0010"},
{"BezeichnungDE":"Sammelbandantrieb"},
{"BezeichnungEN":"Collection belt drive N50"},
{"Einheit":"STK"},
{"MatGrp":"VAU"},
{"Kostenart": 1500},
{"Vertriebstext_DE": "Antrieb, Umlenkungen"},
{"Vertriebstext_EN": "Drive, Deflections"},
{"Stueckliste":"VAUBEF0010"},
{"Status":"F"},
{"Klasse":"VTPIMV"},
{"Mantelflaeche":1.3},
{"Gewicht":120},
{"KlasseID":"1.2.6.5"}],
"Stueckliste": [{"Verkaufsartikel":"VAUBEF0010"},
{"Position": 10},
{"PosArtikel":"Z0306251"},
{"PosBezeichnung":"VEL Elektro- Montagematerial"},
{"PosKostenart":9105},
{"Datum":"2022-01-31"},
{"Material":60.41},
{"GMK":3.63},
{"Lohn":2.07},
{"Menge":1},
{"Mengeneinheit":"STK"}],
"Arbeitsgaenge": [{"Verkaufsartikel":"VAUBEF0010"},
{"AGNR":10},
{"Bereich":"Mechanische Montage"},
{"Lohn":89.1},
{"Kostenstelle":523500},{"ARBPLATZ":"K950M"}]
}
What am i doing wrong?
I tried DeserializeObject with the json you provided
Public Class Artikelstammdaten
Public Property Artikel As String
Public Property BezeichnungDE As String
Public Property BezeichnungEN As String
Public Property Einheit As String
Public Property MatGrp As String
Public Property Kostenart As Integer
Public Property Vertriebstext_DE As String
Public Property Vertriebstext_EN As String
Public Property Stueckliste As String
Public Property Status As String
Public Property Klasse As String
Public Property Mantelflaeche As Double
Public Property Gewicht As Integer
Public Property KlasseID As String
End Class
Public Class ManufacturingCost
Public Property Verkaufsartikel As String
Public Property Position As Integer
Public Property PosArtikel As String
Public Property PosBezeichnung As String
Public Property PosKostenart As Integer
Public Property Datum As String
Public Property Material As Double
Public Property GMK As Double
Public Property Lohn As Double
Public Property Menge As Integer
Public Property Mengeneinheit As String
End Class
Public Class MaterialCost
Public Property Verkaufsartikel As String
Public Property AGNR As Integer
Public Property Bereich As String
Public Property Lohn As Double
Public Property Kostenstelle As Integer
Public Property ARBPLATZ As String
End Class
Public Class Root4
Public Property Artikelstammdaten As List(Of Artikelstammdaten)
Public Property ManufacturingCosts As List(Of ManufacturingCost)
Public Property MaterialCosts As List(Of MaterialCost)
End Class
Private Sub btnJson4_Click(sender As Object, e As EventArgs)
Dim Json As String = "{'Artikelstammdaten':[{'Artikel':'VAUBEF0010'},
{'BezeichnungDE':'Sammelbandantrieb'},
{'BezeichnungEN':'Collection belt drive N50'},
{'Einheit':'STK'},
{'MatGrp':'VAU'},
{'Kostenart': 1500},
{'Vertriebstext_DE': 'Antrieb, Umlenkungen'},
{'Vertriebstext_EN': 'Drive, Deflections'},
{'Stueckliste':'VAUBEF0010'},
{'Status':'F'},
{'Klasse':'VTPIMV'},
{'Mantelflaeche':1.3},
{'Gewicht':120},
{'KlasseID':'1.2.6.5'}],
'ManufacturingCosts': [{'Verkaufsartikel':'VAUBEF0010'},
{'Position': 10},
{'PosArtikel':'Z0306251'},
{'PosBezeichnung':'VEL Elektro- Montagematerial'},
{'PosKostenart':9105},
{'Datum':'2022-01-31'},
{'Material':60.41},
{'GMK':3.63},
{'Lohn':2.07},
{'Menge':1},
{'Mengeneinheit':'STK'}],
'MaterialCosts': [{'Verkaufsartikel':'VAUBEF0010'},
{'AGNR':10},
{'Bereich':'Mechanische Montage'},
{'Lohn':89.1},
{'Kostenstelle':523500},{'ARBPLATZ':'K950M'}]}"
Dim rt4 As New Root4
rt4 = JsonConvert.DeserializeObject(Of Root4)(Json)
Console.WriteLine(rt4.Artikelstammdaten(0).Artikel)
Console.WriteLine(rt4.Artikelstammdaten(1).BezeichnungDE)
End Sub
The json structure you provided and the clss you created are different.
Your problem is that your the values for the JSON properties "Artikelstammdaten", "Stueckliste" and "Arbeitsgaenge" are not objects. They are arrays of single-property objects. This can be seen if you reformat your JSON with e.g. https://jsonlint.com/:
{
"Artikelstammdaten": [{
"Artikel": "VAUBEF0010"
},
{
"BezeichnungDE": "Sammelbandantrieb"
},
{
"BezeichnungEN": "Collection belt drive N50"
},
{
"Einheit": "STK"
},
{
"MatGrp": "VAU"
},
{
"Kostenart": 1500
},
{
"Vertriebstext_DE": "Antrieb, Umlenkungen"
},
{
"Vertriebstext_EN": "Drive, Deflections"
},
{
"Stueckliste": "VAUBEF0010"
},
{
"Status": "F"
},
{
"Klasse": "VTPIMV"
},
{
"Mantelflaeche": 1.3
},
{
"Gewicht": 120
},
{
"KlasseID": "1.2.6.5"
}
],
"Stueckliste": [{
"Verkaufsartikel": "VAUBEF0010"
},
{
"Position": 10
},
{
"PosArtikel": "Z0306251"
},
{
"PosBezeichnung": "VEL Elektro- Montagematerial"
},
{
"PosKostenart": 9105
},
{
"Datum": "2022-01-31"
},
{
"Material": 60.41
},
{
"GMK": 3.63
},
{
"Lohn": 2.07
},
{
"Menge": 1
},
{
"Mengeneinheit": "STK"
}
],
"Arbeitsgaenge": [{
"Verkaufsartikel": "VAUBEF0010"
},
{
"AGNR": 10
},
{
"Bereich": "Mechanische Montage"
},
{
"Lohn": 89.1
},
{
"Kostenstelle": 523500
}, {
"ARBPLATZ": "K950M"
}
]
}
You would like to deserialize those arrays of single-property objects into c# models where each nested JSON property is bound to a model property. Since this is not implemented out of the box by Json.NET, you will need to create a custom generic JsonConverter such as the following:
Public Class ObjectToDictionaryArrayConverter(Of T)
Inherits JsonConverter
Public Overrides Function CanConvert(ByVal objectType As Type) As Boolean
Return objectType Is GetType(T)
End Function
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return False
End Get
End Property
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal objectType As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
If existingValue Is Nothing Then
Dim contract = serializer.ContractResolver.ResolveContract(objectType)
existingValue = contract.DefaultCreator()()
End If
Select Case JsonExtensions.MoveToContentAndAssert(reader).TokenType
Case JsonToken.StartArray
While JsonExtensions.ReadToContentAndAssert(reader).TokenType <> JsonToken.EndArray
Select Case reader.TokenType
Case JsonToken.StartObject
serializer.Populate(reader, existingValue)
Case Else
Throw New JsonSerializationException("Unexpected token type " & reader.TokenType.ToString())
End Select
End While
Case JsonToken.StartObject
serializer.Populate(reader, existingValue)
Case Else
Throw New JsonSerializationException("Unexpected token type " & reader.TokenType.ToString())
End Select
Return existingValue
End Function
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal value As Object, ByVal serializer As JsonSerializer)
Throw New NotImplementedException()
End Sub
End Class
Public Module JsonExtensions
<System.Runtime.CompilerServices.Extension()>
Public Function ReadToContentAndAssert(ByVal reader As JsonReader) As JsonReader
Return JsonExtensions.ReadAndAssert(reader).MoveToContentAndAssert()
End Function
<System.Runtime.CompilerServices.Extension()>
Public Function MoveToContentAndAssert(ByVal reader As JsonReader) As JsonReader
If reader Is Nothing Then Throw New ArgumentNullException()
If reader.TokenType = JsonToken.None Then reader.ReadAndAssert() ' Skip past beginning of stream.
While reader.TokenType = JsonToken.Comment ' Skip past comments.
reader.ReadAndAssert()
End While
Return reader
End Function
<System.Runtime.CompilerServices.Extension()>
Public Function ReadAndAssert(ByVal reader As JsonReader) As JsonReader
If reader Is Nothing Then Throw New ArgumentNullException()
If Not reader.Read() Then Throw New JsonReaderException("Unexpected end of JSON stream.")
Return reader
End Function
End Module
Then modify your RootObject as follows, to replace the lists with single objects:
Public Class RootObject
Public Property Artikelstammdaten As Artikelstammdaten
Public Property Stueckliste As Stueckliste
Public Property Arbeitsgaenge As Arbeitsgaenge
End Class
And deserialize as follows:
Dim root as RootObject = Nothing
If OpenfilePath IsNot Nothing Then
Dim settings = New JsonSerializerSettings() With { .Converters = New JsonConverter() { _
New ObjectToDictionaryArrayConverter(Of Artikelstammdaten)(), _
New ObjectToDictionaryArrayConverter(Of Stueckliste)(), _
New ObjectToDictionaryArrayConverter(Of Arbeitsgaenge)() } }
Using fileReader = New StreamReader(OpenfilePath)
Using jsonReader = New JsonTextReader(fileReader)
root = JsonSerializer.CreateDefault(settings).Deserialize(Of RootObject)(jsonReader)
End Using
End Using
End If
Demo vb.net fiddle here.
Notes:
If you can modify your JSON format so that "Artikelstammdaten", "Stueckliste" and "Arbeitsgaenge" are objects rather than arrays of objects, the converter becomes unnecessary.
For performance reasons, Newtonsoft recommends reading directly from a file using a stream reader.
a StreamReader should always be closed via a Using statement after you are done reading from it.
I did not implement re-serialization of an object as an array of single-property objects because your question did not indicate it was necessary.
In c# ObjectToDictionaryArrayConverter<T> would be as follows:
public class ObjectToDictionaryArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(T);
public override bool CanWrite => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (existingValue == null)
{
var contract = serializer.ContractResolver.ResolveContract(objectType);
existingValue = contract.DefaultCreator();
}
switch (reader.MoveToContentAndAssert().TokenType)
{
case JsonToken.StartArray:
{
while (reader.ReadToContentAndAssert().TokenType != JsonToken.EndArray)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
serializer.Populate(reader, existingValue);
break;
default:
throw new JsonSerializationException("Unexpected token type " + reader.TokenType.ToString());
}
}
}
break;
case JsonToken.StartObject:
serializer.Populate(reader, existingValue);
break;
default:
throw new JsonSerializationException("Unexpected token type " + reader.TokenType.ToString());
}
return existingValue;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
public static partial class JsonExtensions
{
public static JsonReader ReadToContentAndAssert(this JsonReader reader) =>
reader.ReadAndAssert().MoveToContentAndAssert();
public static JsonReader MoveToContentAndAssert(this JsonReader reader)
{
if (reader == null)
throw new ArgumentNullException();
if (reader.TokenType == JsonToken.None) // Skip past beginning of stream.
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.Comment) // Skip past comments.
reader.ReadAndAssert();
return reader;
}
public static JsonReader ReadAndAssert(this JsonReader reader)
{
if (reader == null)
throw new ArgumentNullException();
if (!reader.Read())
throw new JsonReaderException("Unexpected end of JSON stream.");
return reader;
}
}
c# demo fiddle here.
My program accesses data through a Web API and gets data in JSON format. Response is for example:
{
"response":{
"stationId":"24026900",
"prices":[
{
"name":"Aral Super E10",
"price":"146,90",
"currency":"EUR",
"id":"001131",
"sort":"21"
},
{
"name":"Aral Super 95",
"price":"152,90",
"currency":"EUR",
"id":"001040",
"sort":"22"
},
{
"name":"Aral Ultimate 102",
"price":"172,90",
"currency":"EUR",
"id":"001255",
"sort":"24"
},
{
"name":"Aral Diesel",
"price":"130,90",
"currency":"EUR",
"id":"004002",
"sort":"30"
},
{
"name":"Aral Ultimate Diesel",
"price":"150,90",
"currency":"EUR",
"id":"004267",
"sort":"31"
},
{
"name":"Aral LKW Diesel",
"price":"130,90",
"currency":"EUR",
"id":"004010",
"sort":"32"
}
],
"lastUpdate":"202104122030",
"disabled":"false",
"openNow":"Wir haben f\u00fcr Sie ge\u00f6ffnet."
}
}
How can I e.g. access deeply nested data like "price":"172,90".
My structure is like:
Dim sJSON As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim PriceLastValue As String = funcGetPriceInfo("response") 'How to get access to deeper nested data here?
'
'Every key except "response" throws an exception
'
MsgBox(PriceLastValue.ToString)
End Sub
Private Function funcGetPriceInfo(ByVal sVal As String) As String
Dim JSONSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
sJSON = ReadStreamFromWeb.ReadFileFromWeb_WebRequest("http://ap.aral.de/api/v2/getStationPricesById.php?stationId=24026900")
Dim dictJSON As Dictionary(Of String, Object) = JSONSerializer.Deserialize(Of Dictionary(Of String, Object))(sJSON)
Return dictJSON(sVal).ToString
End Function
thank you, really appreciate your help! Now added reference to Newtonsoft and the classes:
Public Class Rootobject
Public Property response As Response
End Class
Public Class Response
Public Property stationId As String
Public Property prices() As Price
Public Property lastUpdate As String
Public Property disabled As String
Public Property openNow As String
End Class
Public Class Price
Public Property name As String
Public Property price As String
Public Property currency As String
Public Property id As String
Public Property sort As String
End Class
And trying to get the object:
sJSON = ReadStreamFromWeb.ReadFileFromWeb_WebRequest("http://ap.aral.de/api/v2/getStationPricesById.php?stationId=24026900")
Dim obj As Rootobject = JsonConvert.DeserializeObject(Of Rootobject)(sJSON)
But this throws..
Newtonsoft.Json.JsonSerializationException: "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'myprog.Form1+Price' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
Below is a json file that needs to be deserialized and to be stored in different variables.
With this current json, which is returned by an API, I am unable to deserialize because it gives me and error -
Please help me on deserializing this particular json
I have added the code i used, but it returns wrong values and null reference.
{
"result": {
"candidates": [
{
"similarity": 0.1330482513,
"person_id": "75741ea3-4d9b-4e25-8460-16444ee39946",
"descriptor_id": "2f228007-350e-4d58-9897-4b62e9978081",
"user_data": "Без названия (9)",
"external_id": null
}
],
"face": {
"id": "a1b224a3-60c6-4733-9bbc-136d53ea011c",
"score": 0.9320185781
}
},
"timestamp": 1569957900.1488559,
"source": "search",
"event_type": "match",
"authorization": {
"token_id": "71f9b3e0-51b1-480f-93b9-0e76e260bcbc",
"token_data": "first token"
},
"template": {
"descriptor_id": "a1b224a3-60c6-4733-9bbc-136d53ea011c"
},
"candidate": {
"list_id": "6e64e600-cd77-4894-940e-6f7022d8aba8",
"list_data": "FaceStream_search_list(DON'T DELETE)",
"list_type": 1
}
}
I have tried :
Public Class Rootobject
Public Property result As Result
Public Property timestamp As Single
Public Property source As String
Public Property event_type As String
Public Property authorization As Authorization
Public Property template As Template
Public Property candidate As Candidate1
End Class
Public Class Result
Public Property candidates() As Candidate
Public Property face As Face
End Class
Public Class Face
Public Property id As String
Public Property score As Single
End Class
Public Class Candidate
Public Property similarity As Double
Public Property person_id As String
Public Property descriptor_id As String
Public Property user_data As String
Public Property external_id As Object
End Class
Public Class Authorization
Public Property token_id As String
Public Property token_data As String
End Class
Public Class template
Public Property descriptor_id As String
End Class
Public Class Candidate1
Public Property list_id As String
Public Property list_data As String
Public Property list_type As Integer
End Class
''And used
Dim Candidatess As New Candidate
Candidatess = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Candidate)((JObject.Parse(e.Message)).ToString)
msg(Candidatess.similarity.ToString)
msg(Candidatess.descriptor_id.ToString)
msg(Candidatess.person_id.ToString)
''REturns me Null
Public Class Candidate
Public Property similarity As Double
Public Property person_id As String
Public Property descriptor_id As String
Public Property user_data As String
Public Property external_id As Object
End Class
Public Class Face
Public Property id As String
Public Property score As Double
End Class
Public Class Result
Public Property candidates As Candidate()
Public Property face As Face
End Class
Public Class Authorization
Public Property token_id As String
Public Property token_data As String
End Class
Public Class Template
Public Property descriptor_id As String
End Class
Public Class Candidate
Public Property list_id As String
Public Property list_data As String
Public Property list_type As Integer
End Class
Public Class Candidates
Public Property result As Result
Public Property timestamp As Double
Public Property source As String
Public Property event_type As String
Public Property authorization As Authorization
Public Property template As Template
Public Property candidate As Candidate
End Class
Public Function GetData(ApiEndpoint As Uri, ApiToken As String)
Dim origResponse As HttpWebResponse = Nothing
Dim objResponse As HttpWebResponse = Nothing
Dim origReader As StreamReader = Nothing
Dim objReader As StreamReader = Nothing
Dim origRequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(ApiEndpoint), HttpWebRequest)
origRequest.Headers.Add("Authorization", "Basic " & ApiToken)
origRequest.AllowAutoRedirect = False
origRequest.Method = "GET"
'Call the API and get the JSON Response data
origResponse = DirectCast(origRequest.GetResponse(), HttpWebResponse)
Dim Stream As Stream = origResponse.GetResponseStream()
Dim sr As New StreamReader(Stream, Encoding.GetEncoding("utf-8"))
Dim myJsonResponse As String = sr.ReadToEnd()
'Deserialize the Json
Dim objFormResults As Result = JsonConvert.DeserializeObject(Of Result)(myJsonResponse)
'loop through the results
End Function
I can't figure it out why ALL fields return null. My classes seem correct and fit the json perfectly. I used the JSON Util tool to convert my JSON result to VB (http://jsonutils.com/). I tried the project in C# but end up resulting the same problem. I'm using RestSharp to make my request and JSON.NET to deserialize my object.
Note that the RestSharp content is not empty and is equal to the JSON i added below.
Here is the Json :
{"customer":{"created_at":"2015-10-10T16:35:07-04:00","cust_identifier":null,"description":null,"domains":null,"id":8000039822,"name":"ACTION VEHICULES D'OCCASION","note":null,"sla_policy_id":8000012148,"updated_at":"2015-10-15T09:43:09-04:00","custom_field":{"cf_etat_client":"NO","cf_dealer_code":"U4504033884","cf_manufacturer":"Used","cf_email":null,"cf_province":"QU\u00c9BEC","cf_region":null,"cf_address":"1913 CH CHAMBLY","cf_city":"CARIGNAN","cf_postal_code":null,"cf_phone_":"450 403-3884","cf_fax":null,"cf_tollfree":null,"cf_legal_name":"ACTION VEHICULES D'OCCASION","cf_dealer_princ":null,"cf_g_manager":null,"cf_cfo_finance":null,"cf_sales_manager":null,"cf_trade_resp":null,"cf_used_veh_manager":null,"cf_business_manager_1":null,"cf_business_manager_2":null,"cf_email_g_manager":null,"cf_email_gs_manager":null,"cf_email_s_manager":null,"cf_email_trade":null,"cf_fleet_lease":null,"cf_accounting":null,"cf_installed":null,"cf_demo":null,"cf_update":null,"cf_sold":null,"cf_dealer_website":null,"cf_i_t_contact":null,"cf_server_name":null,"cf_network":null,"cf_is_domain":null,"cf_easybackup":null,"cf_password":null,"cf_pc_installed":null,"cf_reference_by":null,"cf_error_":null,"cf_license_":null,"cf_is_amvoq":true}}}
Here both of my class i used to deserialize :
Public Class Customer
Public Property created_at As DateTime
Public Property cust_identifier As Object
Public Property description As Object
Public Property domains As Object
Public Property id As Long
Public Property name As String
Public Property note As Object
Public Property sla_policy_id As Long
Public Property updated_at As DateTime
Public Property custom_field As CustomField
End Class
Public Class CustomField
Public Property cf_etat_client As String
Public Property cf_dealer_code As String
Public Property cf_manufacturer As String
Public Property cf_email As Object
Public Property cf_province As String
Public Property cf_region As Object
Public Property cf_address As String
Public Property cf_city As String
Public Property cf_postal_code As Object
Public Property cf_phone_ As String
Public Property cf_fax As Object
Public Property cf_tollfree As Object
Public Property cf_legal_name As String
Public Property cf_dealer_princ As Object
Public Property cf_g_manager As Object
Public Property cf_cfo_finance As Object
Public Property cf_sales_manager As Object
Public Property cf_trade_resp As Object
Public Property cf_used_veh_manager As Object
Public Property cf_business_manager_1 As Object
Public Property cf_business_manager_2 As Object
Public Property cf_email_g_manager As Object
Public Property cf_email_gs_manager As Object
Public Property cf_email_s_manager As Object
Public Property cf_email_trade As Object
Public Property cf_fleet_lease As Object
Public Property cf_accounting As Object
Public Property cf_installed As Object
Public Property cf_demo As Object
Public Property cf_update As Object
Public Property cf_sold As Object
Public Property cf_dealer_website As Object
Public Property cf_i_t_contact As Object
Public Property cf_server_name As Object
Public Property cf_network As Object
Public Property cf_is_domain As Object
Public Property cf_easybackup As Object
Public Property cf_password As Object
Public Property cf_pc_installed As Object
Public Property cf_reference_by As Object
Public Property cf_error_ As Object
Public Property cf_license_ As Object
Public Property cf_is_amvoq As Boolean
End Class
Here is the Deserialize Function :
Public Shared Function JSONDeserializeFreshDeskCie(repContent As Stream) As Customer
Dim rs As Customer = Nothing
Dim test As Object
Dim serializer As New JsonSerializer()
Try
Using sr As New StreamReader(repContent)
Using jsonTextReader As New JsonTextReader(sr)
rs = serializer.Deserialize(Of Customer)(jsonTextReader)
End Using
End Using
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
Return rs
End Function
Here where i call my function to retrieve my object :
Private Sub loadAllCie(ByVal e As IRestResponse)
Dim rep As Stream = Nothing
Dim rs As Customer
Try
rep = New MemoryStream(e.RawBytes())
If e.ErrorException IsNot Nothing OrElse e.StatusCode <> Net.HttpStatusCode.OK Then
Dim strError As String = ""
If e.ErrorException IsNot Nothing Then
strError = "Error : " & e.ErrorException.Message & vbCrLf
End If
strError &= "Web Error : " & e.ErrorMessage
strError &= vbCrLf & e.StatusCode.ToString()
MessageBox.Show(strError)
Exit Try
End If
rs = JSONSerialization.JSONDeserializeFreshDeskCie(rep)
Dim allo As String = ""
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
If rep IsNot Nothing Then
rep.Close()
End If
End Try
End Sub
Look at the start of the JSON:
{"customer":{"created_at"...
There is an outer container created to hold "customer" which your code does not account for. If you do not want to create a do-nothing class for it, parse the result first:
Dim jstr = ...from whereever
Dim jobj = JObject.Parse(jstr)
Dim cust = JsonConvert.DeserializeObject(Of Customer)(jobj("customer").ToString)
To use a class:
Public Class CustContainer
Public Property customer As Customer
End Class
...
Dim cust = JsonConvert.DeserializeObject(Of CustContainer)(jstr)
I dont like the second because it requires all the rest of the references to be cust.customer.Foo, so I prefer to discard them.