This question already has answers here:
Deserializing JSON when sometimes array and sometimes object
(7 answers)
Closed 2 years ago.
I get an API response in JSON in following format
{
"stuffs": {
"prop1": "abcd",
"prop2": "efgh",
"prop3": [
{
"content": "123456",
"name": "abc def",
"id": "123"
},
{
"content": "789012",
"name": "def ghi",
"id": "456"
}
]
}
}
I have created my Class to deserialize this object as below
Public Class Prop3
Public Property content As String
Public Property name As String
Public Property id As String
End Class
Public Class Stuffs
Public Property prop1 As String
Public Property prop2 As String
Public Property prop3 As Prop3()
End Class
Public Class Example
Public Property stuffs As Stuffs
End Class
Now the issue is, sometime, the response is not an array for prop3 and looks like this
{
"stuffs": {
"prop1": "abcd",
"prop2": "efgh",
"prop3": {
"content": "123456",
"name": "abc def",
"id": "123"
}
}
}
This time I get error while deserializing as the prop3 is not array anymore bu the property declared inside my class stuffs is expecting an array of property prop3.
Is there any dynamic way to resolve this? Like if the JSON response is an array it will be treated as array
Public Property prop3 As Prop3()
and in case it is not an array then it will treated as single property
Public Property prop3 As Prop3
Please suggest how to overcome this as changing the response from the API is not feasible because it is being developed by client and I need to use it my application, so I need to find some dynamic way to resolve this.
After suggestion made by Craig, I have tried in the below way, but still it is not happening, please suggest if I am making any mistake.
Public Class SingleValueArrayConverter(Of T)
Inherits JsonConverter
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal value As Object, ByVal serializer As JsonSerializer)
serializer.Serialize(writer, value)
End Sub
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal objectType As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
Dim retVal As Object = New Object()
If reader.TokenType = JsonToken.StartObject Then
Dim instance As T = CType(serializer.Deserialize(reader, GetType(T)), T)
retVal = New List(Of T)() From {
instance
}
ElseIf reader.TokenType = JsonToken.StartArray Then
retVal = serializer.Deserialize(reader, objectType)
End If
Return retVal
End Function
Public Overrides Function CanConvert(ByVal objectType As Type) As Boolean
Return True
End Function
End Class
Public Class myClass1
Public Class Prop3
Public Property content As String
Public Property name As String
Public Property id As String
End Class
Public Class Stuffs
Public Property prop1 As String
Public Property prop2 As String
<JsonProperty("prop3")>
<JsonConverter(GetType(SingleValueArrayConverter(Of Prop3)))>
Public Property prop3 As Prop3()
End Class
Public Class Example
Public Property stuffs As Stuffs
End Class
End Class
It gives error:
Unable to cast object of type 'SingleValueArrayConverter`1[myClass1.myClass+Prop3]' to type 'Newtonsoft.Json.JsonConverter'.'
Any highlight on what I am missing please.
It worked after changing
Public Property prop3 As Prop3()
to
Public Property prop3 As List(Of Prop3)
Related
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.
I have been trying to deserialize json string in vb.net. I am able successfully get a response using
Using myResp = TryCast(myReq.GetResponse(), System.Net.HttpWebResponse)
Using myReader = New System.IO.StreamReader(myResp.GetResponseStream())
responseContent = myReader.ReadToEnd()
End Using
End Using
responseContent:
{
"devices": {
"totalCount": 1,
"totalPage": 1,
"pageNum": 0,
"transactions": [{
"transactionId": "20211005200111",
"state": "Complete",
"type": "Put",
"operationType": "UPLOAD",
"devices": [{
"imei": "357452100344123",
"code": 40000004,
"message": "DEVICE_INVALID",
"data": "The specified device is not valid."
}, {
"imei": "357452100344409",
"code": 40000005,
"message": "DEVICE_DUPLICATE",
"data": "The specified device already exists."
}]
}]
created classes to hold data:
Public Class devices
Public Property devicelist As List(Of device)
End Class
Public Class device
Public Property pageNum As Integer
Public Property totalCount As Integer
Public Property totalPage As Integer
Public Property transactions As List(Of transaction)
End Class
Public Class transaction
Public Property transactionId As String
Public Property state As String
Public Property type As String
Public Property operationType As String
Public Property devices As List(Of mydevice)
End Class
Public Class mydevice
Public Property imei As String
Public Property code As Integer
Public Property message As String
Public Property data As String
End Class
When I attempt to deserialize, no error is thrown however nothing gets populated:
VB debug
Please let me know what I may be doing wrong?
As for my thoughts,
First of all, it looks like the Json form is wrong.
The last point }} is missing.
Second, Object is wrong.
The property name must be the same as the Json name.
If property name is different, it should be marked using JsonProperty.
I applied the contents and made a test source.
Public Class root
<JsonProperty("devices")>
Public Property devicelist As devices
End Class
Public Class devices
Public Property pageNum As Integer
Public Property totalCount As Integer
Public Property totalPage As Integer
Public Property transactions As List(Of transaction)
End Class
Public Class transaction
Public Property transactionId As String
Public Property state As String
Public Property type As String
Public Property operationType As String
Public Property devices As List(Of mydevice)
End Class
Public Class mydevice
Public Property imei As String
Public Property code As Integer
Public Property message As String
Public Property data As String
End Class
Private Sub test()
Try
Dim Json As String = "{
'devices': {
'totalCount': 1,
'totalPage': 1,
'pageNum': 0,
'transactions': [{
'transactionId': '20211005200111',
'state': 'Complete',
'type': 'Put',
'operationType': 'UPLOAD',
'devices': [{
'imei': '57452100344123',
'code': 40000004,
'message': 'DEVICE_INVALID',
'data': 'The specified device is not valid.'
}, {
'imei': '357452100344409',
'code': 40000005,
'message': 'DEVICE_DUPLICATE',
'data': 'The specified device already exists.'
}]
}]
}}"
Dim ds As root = JsonConvert.DeserializeObject(Of root)(Json)
Dim d As devices = ds.devicelist
Console.WriteLine(d.pageNum)
Console.WriteLine(d.totalCount)
Console.WriteLine(d.totalPage)
For Each tran In d.transactions
Console.WriteLine(tran.transactionId)
For Each dd In tran.devices
Console.WriteLine(dd.code)
Next
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
I have this json response:
{
"tracked_until": "1483704963",
"solo_competitive_rank": "4066",
"competitive_rank": "3821",
"mmr_estimate": {
"estimate": 3971,
"stdDev": 215.26495302301302,
"n": 20
},
"profile": {
"account_id": 131505839,
"personaname": "LeG",
"name": null,
"cheese": 1,
"steamid": "76561198091771567",
"avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/c0/c09ca9b316ff7bf7dccba6f5a32aba97b8dba05c.jpg",
"avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/c0/c09ca9b316ff7bf7dccba6f5a32aba97b8dba05c_medium.jpg",
"avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/c0/c09ca9b316ff7bf7dccba6f5a32aba97b8dba05c_full.jpg",
"profileurl": "http://steamcommunity.com/id/LegLabs/",
"last_login": "2016-11-11T13:13:18.651Z",
"loccountrycode": "AL"
}
}
Using an Online Tool, I created these classes:
<Serializable>
Public Class mmr_estimate
Public Property estimate As String
Public Property stdDev As String
Public Property n As String
End Class
<Serializable>
Public Class profile
Public Property account_id As String
Public Property personaname As String
Public Property name As String
Public Property cheese As String
Public Property steamid As String
Public Property avatar As String
Public Property avatarmedium As String
Public Property avatarfull As String
Public Property profileurl As String
Public Property last_login As String
Public Property loccountrycode As String
End Class
<Serializable>
Public Class RootObject
Public Property tracked_until As String
Public Property solo_competitive_rank As String
Public Property competitive_rank As String
Public Property mmr_estimate As mmr_estimate
Public Property profile As profile
End Class
Then I use this code to deserialize it:
Dim steamData As String = ' the json contents above
Dim myjss As New JavaScriptSerializer()
Dim playerDictionary = myjss.Deserialize(Of List(Of RootObject))(steamData)
But the result I get is nothing, playerDictionary has 0 items, when it should have 1 item with the contents of the json parsed into KeyValuePairs.
If I use this piece of code
Dim data = myjss.DeserializeObject(steamData)
and then run a for each loop on the data elements, I can see the contents of data when debugging, but I don't know how to work with them like that, since they are just objects which I'm having trouble converting into KeyValuePairs, who in themselves may contain arrays of KeyValuePairs.
What I'm trying to get is the values of solo_competitive_rank, competitive_rank and steamid, but if I can't get the whole contents deserialized, I can't do that.
Are the declared classes wrong?
but with this solution you use not the class RootObject.
With first method, your JSON want in the list with key and value.
This is only for JSON Array. :(
rg
I am consuming a web service that is sending multiple objects in a json string.
{ "id": null, "method": "ready", "params": [ { "accept": 1, "serial": "001d50101979" },
{
"result": {
"serial": "001d50101979",
"name": "001d50101979",
"model": "HMP200",
"mode": "normal",
"firmware": {
"version": "3.2.2-1.0.28801",
"status": "normal"
},
"uptime": "233.50",
"bootid": "e62f7839-95b1-4775-8476-c0b1b5b4857f"
},
"error": null,
"id": 1231
} ] }
I am using the following classes
Public Class Firmware
Public Property version As String
Public Property status As String
End Class
Public Class Result
Public Property serial As String
Public Property name As String
Public Property model As String
Public Property mode As String
Public Property firmware As Firmware
Public Property uptime As String
Public Property bootid As String
End Class
Public Class Param
Public Property accept As Integer
Public Property serial As String
End Class
Public Class Player
Public Property id As Object
Public Property method As String
Public Property params As Param()
End Class
I have no issue deserializing the root class Player but I am not sure how to deserialize the class Result.
Dim Player As New Player
Player = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Player)(JsonString)
Dim FirmwareVersion As String = Player.id
Dim bootid As String = Player.method
Dim Model As String = Player.params(0).accept
Dim Serial As String = Player.params.ElementAt(0).serial
Change your class Param to
Public Class Param
Public Property accept As Integer
Public Property serial As String
Public Property result As Result
End Class
then you can access your result like so
Dim Player As New Player
Player = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Player)(JsonString)
Dim FirmwareVersion As String = Player.id
Dim bootid As String = Player.method
Dim Model As String = Player.params(0).accept
Dim Serial As String = Player.params.ElementAt(0).serial
For Each p In Player.params
If p.result IsNot Nothing Then
Console.WriteLine(p.result.model)
End If
Next
When I de-serialize/serialize and data contract to a json format my collection of items is missing the bracket and is causing it fail when posting to web api.
Here is the json in the correct format with [] brackets
{
"basket": {
"basket_platform_type": "in_store",
"basket_currency": {
"currency_id": 2,
"currency_code": "ZAR"
},
"basket_items": [
{
"spaaza_product_id": 18605,
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_0",
"item_quantity": 3,
"item_price": 250
}
],
"retailer_basket_code": "70401",
"basket_total_price": 750
},
"entity": {
"entity_type": "chain",
"entity_id": 1740,
"branch_business_owner_code": "501",
"branch_business_id": 1341
},
"user": {
"member_programme": "spaaza",
"member_number": "33017307"
}
}
This is what I get, I am missing the [] at basketitems
{
"basket": {
"basket_platform_type": "in_store",
"basket_currency": {
"currency_id": 2,
"currency_code": "ZAR"
},
"basket_items":
{
"spaaza_product_id": 18605,
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_0",
"item_quantity": 3,
"item_price": 250
},
"retailer_basket_code": "70401",
"basket_total_price": 750
},
"entity": {
"entity_type": "chain",
"entity_id": 1740,
"branch_business_owner_code": "501",
"branch_business_id": 1341
},
"user": {
"member_programme": "spaaza",
"member_number": "33017307"
}
}
Here is classes and the functions I am using for serialization.
Namespace Global.MyPrice
Public Class GetBasketPrice
Public Class Entity
Public Property entity_type As String
Public Property entity_id As Integer
Public Property branch_business_owner_code As String
Public Property branch_business_id As Integer
End Class
Public Class User
Public Property member_programme As String
Public Property member_number As String
End Class
Public Class Basket_Currency
Public Property currency_id As Integer
Public Property currency_code As String
End Class
Public Class Rootobject
Public Property basket As Basket
Public Property entity As Entity
Public Property user As User
End Class
Public Class Basket_Items
Public Property spaaza_product_id As Integer
Public Property retailer_product_code As String
Public Property retailer_item_code As String
Public Property item_quantity As Integer
Public Property item_price As Single
End Class
Public Class Basket
Public Property basket_platform_type As String
Public Property basket_currency As Basket_Currency
Public Property basket_items() As Basket_Items
Public Property retailer_basket_code As String
Public Property basket_total_price As Single
End Class
End Class
End Namespace
This is the serialization function
Dim jsonstring As String
Dim stream1 As New MemoryStream()
Dim ser As New DataContractJsonSerializer(GetType(MyPrice.GetBasketPrice.Rootobject))
ser.WriteObject(stream1, MyPriceBasket)
stream1.Position = 0
Dim sr As New StreamReader(stream1)
Console.Write("JSON form of Person object: ")
jsonstring = sr.ReadToEnd()
Console.WriteLine(jsonstring)
The value for "basket_items" is a JSON array, which is a bracketed list of values: [value1, value2, ..., valueN]. According to the documentation, DataContractJsonSerializer maps "Collections, dictionaries, and arrays" to a JSON array. Thus your basket_items property needs to be a collection of some sort, for instance a List(Of Basket_Items):
Public Class Basket
Public Property basket_platform_type As String
Public Property basket_currency As Basket_Currency
Public Property basket_items As List(Of Basket_Items)
Public Property retailer_basket_code As String
Public Property basket_total_price As Single
End Class
Or, if you want to use an array rather than a list, your () is in the wrong location. You define an array-valued property in VB.NET like this:
Public Property basket_items As Basket_Items()
More here.