Deserializing nested json into vb.net class using json.net - json

I have some json which I am trying to deserialise into some vb.net objects
Here are the classes
<Serializable()>
Public Class DPDError
Public Property errorAction As String
Public Property errorCode As String
Public Property errorMessage As String
Public Property errorObj As String
Public Property errorType As String
End Class
<Serializable()>
Public Class DPDCountry
Public Property countryCode As String
Public Property countryName As String
Public Property isoCode As String
Public Property isEUCountry As Boolean
Public Property isLiabilityAllowed As Boolean
Public Property liabilityMax As Integer
Public Property isPostcodeRequired As Boolean
End Class
'----- USED TO GET ALL COUNTRY INFO
<Serializable()>
Public Class DPDMultiCountryDataResponse
Public Property Countries as List(Of DPDCountry)
End Class
<Serializable()>
Public Class DPDMultiCountryDataRequest
Public Property DpdError As DPDError
Public Property Data As DPDMultiCountryDataResponse
End Class
Here is the JSON:
{
"data": {
"country": [
{
"countryCode": "UY",
"countryName": "Uruguay",
"isoCode": "858",
"isEUCountry": false,
"isLiabilityAllowed": true,
"liabilityMax": 15000,
"isPostcodeRequired": true
},
{
"countryCode": "US",
"countryName": "Usa",
"isoCode": "840",
"isEUCountry": false,
"isLiabilityAllowed": true,
"liabilityMax": 15000,
"isPostcodeRequired": true
},
{
"countryCode": "VU",
"countryName": "Vanuatu",
"isoCode": "548",
"isEUCountry": false,
"isLiabilityAllowed": true,
"liabilityMax": 15000,
"isPostcodeRequired": true
},
{
"countryCode": "VN",
"countryName": "Vietnam",
"isoCode": "704",
"isEUCountry": false,
"isLiabilityAllowed": true,
"liabilityMax": 15000,
"isPostcodeRequired": true
}
]
}
}
Here is the code to deserialise it
Dim oResponseData As DPDMultiCountryDataRequest = _
JsonConvert.DeserializeObject(Of DPDMultiCountryDataRequest)(tmp)
The countries list is always nothing. The higher level ones are fine. I also have a routine which gets ONE country info which works fine. Its the multiple countries that is killing me.
I have tried an array, an iList, a dictionary and the list as above and nothing works.

The property must be called Country, not Countries:
<Serializable()>
Public Class DPDMultiCountryDataResponse
Public Property Country as List(Of DPDCountry)
Alternatively you could use the JsonProperty attribute:
<Serializable()>
Public Class DPDMultiCountryDataResponse
<JsonProperty(PropertyName = "Country")>
Public Property Countries as List(Of DPDCountry)
Also bear in mind that the Serializable attribute is not needed. It is used only for binary serialization.

Your json contains property named country, but your object contains property that is called Countries:
Public Property Countries as List(Of DPDCountry)
When deserializing json names definitely matter. Update the name to Country:
Public Property Country as List(Of DPDCountry)

Related

VB.NET Deserialize JSON with Newton

I'm trying to get to the next level of information from a jSon response.
I can get "code", but I need to get the "result" and some other information that's under "payload".
I don't have a ton of experience with this, so any help would be appreciated!
Here's my code
Dim jason As String = str
Dim parsejson As New JObject
parsejson = JObject.Parse(jason)
Dim theResponseYo As String = parsejson.SelectToken("code").ToString()
MsgBox("You are: " + theResponseYo)
Here's the json I'm parsing:
{
"code": "200",
"status": "success",
"exchange-id": "xxxxxxx",
"payload": {
"transaction": {
"amount": "2.30",
"id": "115340330",
"created": "2022-07-26 20:07:21.157",
"type": "SALE",
"result": "APPROVED",
"card": "XXXXXXXXXXXX1111",
"csc": "999",
"authorization-code": "TAS185",
"batch-string-id": "10",
"display-message": "Transaction approved",
"result-code": "000",
"exp-date": "1222",
"card-type": "VISA",
"sales-tax-amount": "3.00",
"last-four": "1111",
"service-fee": "1.00",
"merchant-id": "12345567",
"terminal-id": "10011111",
"level3": {
"vat-tax-amount": "0.00",
"vat-tax-rate": "0.00",
"order-date": "20220726",
"discount-amount": "0.00",
"destination-country-code": "USA",
"freight-amount": "0.00",
"duty-amount": "0.00",
"level3-items": {
"level3-items": [
{
"item-description": "PRODUCT",
"item-commodity-code": "UPC",
"item-quantity": "1.00",
"item-unit-of-measure": "EA",
"item-product-code": "MATERIAL",
"item-tax-rate": "0.00",
"item-discount": "0.00",
"item-discount-rate": "0.00"
}
]
}
}
},
"payloadType": "transaction"
}
}
There are 2 ways - you can create VB.Net classes and deserialize instead of parsing if you need the most data, or if you need only several values you can do it like this
Dim code As String = parsejson("code").ToString()
Dim code As String = parsejson("payload")("transaction")("result").ToString()
if you want to deserialize
Dim data as Data = JsonConvert.DeserializeObject(Of Data)(jason)
classes
Public Class Data
Public Property code As String
Public Property status As String
Public Property exchange-id As String
Public Property payload As Payload
End Class
Public Class Level3Items
Public Property item-description As String
Public Property item-commodity-code As String
Public Property item-quantity As String
Public Property item-unit-of-measure As String
Public Property item-product-code As String
Public Property item-tax-rate As String
Public Property item-discount As String
Public Property item-discount-rate As String
End Class
Public Class Level3Items
Public Property level3-items As Level3Items()
End Class
Public Class Level3
Public Property vat-tax-amount As String
Public Property vat-tax-rate As String
Public Property order-date As String
Public Property discount-amount As String
Public Property destination-country-code As String
Public Property freight-amount As String
Public Property duty-amount As String
Public Property level3-items As Level3Items
End Class
Public Class Transaction
Public Property amount As String
Public Property id As String
Public Property created As String
Public Property type As String
Public Property result As String
Public Property card As String
Public Property csc As String
Public Property authorization-code As String
Public Property batch-string-id As String
Public Property display-message As String
Public Property result-code As String
Public Property exp-date As String
Public Property card-type As String
Public Property sales-tax-amount As String
Public Property last-four As String
Public Property service-fee As String
Public Property merchant-id As String
Public Property terminal-id As String
Public Property level3 As Level3
End Class
Public Class Payload
Public Property transaction As Transaction
Public Property payloadType As String
End Class

Deserialize multilevel JSON string with vb.net

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

Serialization of nested JSON with objects

I need to create a JSON that will look as below.
{
"ShipmentId": "111888",
"BizId": "MORRIS",
"BizSalesOrder": null,
"Status": "00",
"OrderType": "S01",
"OrderClass": "PACKSHIP",
"ShipmentLines": [
{
"ShipmentId": "111888",
"QtyOrdered": 30.00,
"QtyRequired": 30.00,
"QtyDueOut": 0.00,
"SOLineId": 1.00,
"Stage": "90"
},
{
"ShipmentId": "111888",
"QtyOrdered": 40.00,
"QtyRequired": 40.00,
"QtyDueOut": 0.00,
"SOLineId": 2.00,
"Stage": "90"
},
{
"ShipmentId": "111888",
"QtyOrdered": 10.00,
"QtyRequired": 10.00,
"QtyDueOut": 0.00,
"SOLineId": 3.00,
"Stage": "90"
},
{
"ShipmentId": "111888",
"QtyOrdered": 5.00,
"QtyRequired": 5.00,
"QtyDueOut": 0.00,
"SOLineId": 4.00,
"Stage": "90"
}
],
"ShipAddress": [
{
"Table": "SHH",
"ShipmentId": "111888",
"AddressId": "ADD1",
"Name": "John Smith",
"Line1": "20 Michelin Ave",
"Line2": null,
"City": "LONDON",
"Postcode": "A99 9BC",
"Country": "GB"
}
],
"ShipContacts": [],
"ShipmentDespatch": []
}
I have classes from http://www.jsonutils.com/ (below) yet I'm pretty sure that ShipmentLines should be a "list(of ShipmentLine)", but that's still quite confusing for me..
Public Class ShipmentLine
Public Property ShipmentId As String
Public Property QtyOrdered As Double
Public Property QtyRequired As Double
Public Property QtyDueOut As Double
Public Property SOLineId As Double
Public Property Stage As String
End Class
Public Class ShipAddress
Public Property Table As String
Public Property ShipmentId As String
Public Property AddressId As String
Public Property Name As String
Public Property Line1 As String
Public Property Line2 As Object
Public Property City As String
Public Property Postcode As String
Public Property Country As String
End Class
Public Class Shipment
Public Property ShipmentId As String
Public Property BizId As String
Public Property BizSalesOrder As Object
Public Property Status As String
Public Property OrderType As String
Public Property OrderClass As String
Public Property ShipmentLines As List(Of ShipmentLine)
Public Property ShipAddress As List(Of ShipAddress)
Public Property ShipContacts As Object()
Public Property ShipmentDespatch As Object()
End Class
I can do 1 level JSON (below), but i have problems with nested (and) multiple objects in 1 nest issue.
I'm new to VB.NET and an amateur in programming(as you can see), so clear instructions would be appreciated.
Shipping Lines are all in Listview1 (left to right from ShipmentId to Stage) so I'm not really sure how to get them and serialize them from Listview1 into a JSON neither.
If you could please write a code for me on how to serialize it what i have got below, but this is only level one of json, no nesting...
Please help, I've been through StackOverflow forum a lot and I'm just repeating all posts now and I can't understand them...
Dim Ship As New Shipment
Ship.ShipmentId = TextBox1.Text
Ship.BizId = TextBox2.Text
Ship.Status = "00"
Ship.OrderType = TextBox3.Text
Ship.Type = TextBox4.Text
Ship.OrderClass = TextBox5.Text
Dim json As String = JsonConvert.SerializeObject(Ship).ToString
It can be done in multiple ways but I followed what you did.
This is what I did:
Imports Newtonsoft.Json
Public Class Form1
Public Class Shipment
Public Property ShipmentId As String
Public Property BizId As String
Public Property BizSalesOrder As Object
Public Property Status As String
Public Property OrderType As String
Public Property OrderClass As String
Public Property ShipmentLines As List(Of ShipmentLine)
Public Property ShipAddress As ShipAddress
Public Property ShipContacts As Object()
Public Property ShipmentDespatch As Object()
End Class
Public Class ShipmentLine
Public Property ShipmentId As String
Public Property QtyOrdered As Double
Public Property QtyRequired As Double
Public Property QtyDueOut As Double
Public Property SOLineId As Double
Public Property Stage As String
End Class
Public Class ShipAddress
Public Property Table As String
Public Property ShipmentId As String
Public Property AddressId As String
Public Property Name As String
Public Property Line1 As String
Public Property Line2 As Object
Public Property City As String
Public Property Postcode As String
Public Property Country As String
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim NewShipment As New Shipment With {
.ShipmentId = "111888",
.BizId = "MORRIS",
.BizSalesOrder = "null",
.Status = "00",
.OrderType = "S01",
.OrderClass = "PACKSHIP"
}
Dim NewShipmentLines As New List(Of ShipmentLine)
For x = 0 To 3
Dim NewShipmentLine As New ShipmentLine
NewShipmentLine.ShipmentId = "111888"
NewShipmentLine.QtyOrdered = x
NewShipmentLine.QtyDueOut = x
NewShipmentLine.SOLineId = x
NewShipmentLine.Stage = x
NewShipmentLines.Add(NewShipmentLine)
Next
NewShipment.ShipmentLines = NewShipmentLines
Dim NewShipAdress As New ShipAddress With {
.Table = "SHH",
.ShipmentId = "111888",
.AddressId = "ADD1",
.Name = "John Smith",
.Line1 = "20 Michelin Ave",
.Line2 = "null",
.City = "LONDON",
.Postcode = "A99 9BC",
.Country = "GB"
}
NewShipment.ShipAddress = NewShipAdress
NewShipment.ShipContacts = Nothing
NewShipment.ShipmentDespatch = Nothing
Dim ResultJSON As String = JsonConvert.SerializeObject(NewShipment).ToString
Debug.Print(ResultJSON) '
End Sub
End Class
And the result:
{
"ShipmentId":"111888",
"BizId":"MORRIS",
"BizSalesOrder":"null",
"Status":"00",
"OrderType":"S01",
"OrderClass":"PACKSHIP",
"ShipmentLines":[
{
"ShipmentId":"111888",
"QtyOrdered":0.0,
"QtyRequired":0.0,
"QtyDueOut":0.0,
"SOLineId":0.0,
"Stage":"0"
},
{
"ShipmentId":"111888",
"QtyOrdered":1.0,
"QtyRequired":0.0,
"QtyDueOut":1.0,
"SOLineId":1.0,
"Stage":"1"
},
{
"ShipmentId":"111888",
"QtyOrdered":2.0,
"QtyRequired":0.0,
"QtyDueOut":2.0,
"SOLineId":2.0,
"Stage":"2"
},
{
"ShipmentId":"111888",
"QtyOrdered":3.0,
"QtyRequired":0.0,
"QtyDueOut":3.0,
"SOLineId":3.0,
"Stage":"3"
}
],
"ShipAddress":{
"Table":"SHH",
"ShipmentId":"111888",
"AddressId":"ADD1",
"Name":"John Smith",
"Line1":"20 Michelin Ave",
"Line2":"null",
"City":"LONDON",
"Postcode":"A99 9BC",
"Country":"GB"
},
"ShipContacts":null,
"ShipmentDespatch":null
}
Obviously you will need to adapt it to work for you, but it works. Sorry I didn't comment anything, if you got questions, ask.

Generating Class VB.NET

I was using JSON Utils to generate a Class and I came to a problem. The JSON string I'm using:
{
"type": "champion",
"version": "7.16.1",
"data": {
"1": {
"title": "the Dark Child",
"id": 1,
"key": "Annie",
"name": "Annie"
}
}
}
The Class it generates:
Public Class 1
Public Property title As String
Public Property id As Integer
Public Property key As String
Public Property name As String
End Class
Public Class Data
Public Property 1 As 1
End Class
Public Class Example
Public Property type As String
Public Property version As String
Public Property data As Data
End Class
The thing is that I cannot name a Class 1, I am still trying to find a solution but with no luck yet. Is there a work around this?
I think it should be change to Dictionary
Public Class Example
Public Property type As String
Public Property version As String
Public Property data As Dictionary(Of String, NumberType)
End Class
Public Class NumberType
Public Property title As String
Public Property id As Integer
Public Property key As String
Public Property name As String
End Class

DataContract Json Serializer and missing bracket in collection of items

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.