Deserialize JSON string (without root)to object VB.NET - json

I,
i need to deserialize a sting that contain JSON formatted data but without root element
the data(simplified!) are this
[{"ID":"974",
"DataIns":"2022-08-12 14:13:26",
"NumeroFattura":"CTD18473",
"DataFattura":"2022-08-08",
"RagSocMit":"Example1"},
{"ID":"973",
"DataIns":"2022-08-12 13:31:00",
"NumeroFattura":"CTCC10189",
"DataFattura":"2022-08-08",
"RagSocMit":"Example2"},
{"ID":"971",
"DataIns":"2022-08-09 15:30:29",
"NumeroFattura":"C18474",
"DataFattura":"2022-08-08",
"RagSocMit":"Example2"}]
and the class for deserializing are this
Public Class TestClass
Public Property ID As String
Public Property DataIns As String
Public Property NumeroFattura As String
Public Property DataFattura As String
Public Property RagSocMit As String
End Class
If i try to deserialize with this code
Dim result As String = ""
Dim ListaFatture As FattureAC2
...
result = reader.ReadToEnd'contain the sting json from a WS
ListaFatture = JsonConvert.DeserializeObject(Of IEnumerable(Of FattureAC2))(result)
ListaFatture are equal to NOTHING
Someone can help me?
Tnx
Salvo

you can not deserialize as IEnumerable, you have to select what do you need an array or list for example
Dim ListaFatture As List (Of TestClass)
ListaFatture = JsonConvert.DeserializeObject(Of List(Of TestClass))(result)

Related

How to parse a big JSON

I'm trying to parse a big JSON and I only need few things from it.
I've been trying to beautify it but I'm having trouble also because it seems that's not completely correct.
This is the website
and I've tried to delete all the unnecessary json
ending up with
[
[
"updateGlobalData",
{
"backgroundData":{
"cities":[
{
"type":"city",
"name":"Polis",
"id":186979,
"level":35,
"ownerId":"99253",
"ownerName":"D3vil666",
"ownerAllyId":"0",
"hasTreaties":0,
"actions":[
],
"state":"vacation",
"viewAble":1,
"infestedByPlague":false
},
{
"type":"city",
"name":"London",
"id":378440,
"level":28,
"ownerId":"242906",
"ownerName":"Mattia",
"ownerAllyId":"5541",
"ownerAllyTag":"LORDS",
"hasTreaties":0,
"actions":[
],
"state":"",
"viewAble":2,
"infestedByPlague":false
}
]
}
}
]
]
The properties I'm looking for are "State" and "ownerName".
State can be "vacation" like ""state"": ""vacation"" or "" like ""state"": """"
These properties are often repeated so I'm only looking for to parse them only once.
For example:
I want to know which state Mattia has and it should return "nothing".
Which state D3vil666 has and it should return "vacation".
The code I'm using:
Public Class Form1
Public Class GlobalData
Public Class BackgroundData
Public Property Cities As List(Of City)
End Class
Public Class City
Public Property Type As String
Public Property Name As String
Public Property OwnerName As String
Public Property State As String
End Class
Public Property BackgroundDataa As BackgroundData
End Class
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim client As New WebClient()
Dim jsonString As String = client.DownloadString("https://s10-it.ikariam.gameforge.com/?view=updateGlobalData&islandId=1649&backgroundView=island&currentIslandId=1649&actionRequest=90983fef22b312ff7cbd51f0183bc301&ajax=1")
Dim data As List(Of GlobalData) = JsonConvert.DeserializeObject(Of List(Of GlobalData))(jsonString)
Dim state = data(0).BackgroundDataa.Cities.FirstOrDefault(Function(x) x.OwnerName = "Mattia").State
MsgBox(state)
End Sub
End Class
but I'm getting the error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Ikariam_VM.Form1+GlobalData' 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 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 '[0]', line 1, position 2.'
I'm working on winform App for .net6+ and using the nuget Newtonsoft package to handle the json.
Any idea?
Thanks
edit1:
Code after suggestions
Imports System.Net
Imports System.Net.Http
Imports System.Net.WebRequestMethods
Imports System.Runtime.InteropServices.JavaScript.JSType
Imports System.Text.Json
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2
Imports Microsoft.Web.WebView2.WinForms
Imports System.Threading
Imports System.IO
Imports System.Runtime.InteropServices.JavaScript
Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json
Public Class Form1
Public Class GlobalData
Public Class BackgroundData
Public Property Cities As List(Of City)
End Class
Public Class City
Public Property Type As String
Public Property Name As String
Public Property OwnerName As String
Public Property State As String
End Class
End Class
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim client As New WebClient()
Dim jsonString As String = client.DownloadString("https://s10-it.ikariam.gameforge.com/?view=updateGlobalData&islandId=1649&backgroundView=island&currentIslandId=1649&actionRequest=90983fef22b312ff7cbd51f0183bc301&ajax=1")
Dim jArr = JArray.Parse(jsonString)
Dim cities = TryCast(jArr(0).OfType(Of JObject)() _
.Select(Function(p) p.Properties().Where(Function(p) p.Name = "backgroundData").First()) _
.FirstOrDefault().Value("cities"),
JArray)
Dim state As String = Nothing
If cities IsNot Nothing Then
state = CStr(cities.Where(Function(c) CStr(c("OwnerName") = "D3vil666")) _
.FirstOrDefault()("state"))
End If
End Sub
End Class
You don't need any custom classes to get data you need from a json string you posted. I haven't a VB.Net compillator so I post my code in c#. I hope you will find somebody to tranclate it to VB.Net
var jArr = JArray.Parse(json);
var cities = jArr[0].OfType<JObject>()
.Select(p => p.Properties().Where(p => p.Name == "backgroundData").First())
.FirstOrDefault().Value["cities"] as JArray;
string state=null;
if (cities != null)
state = (string)cities.Where(c => (string)c["ownerName"] == "D3vil666")
.FirstOrDefault()["state"]; // "vacation"
Serge's answer, translated into VB:
Dim jArr = JArray.Parse(json)
Dim cities = TryCast(jArr(0).OfType(Of JObject)() _
.Select(Function(p) p.Properties().Where(Function(q) q.Name = "backgroundData").First()) _
.FirstOrDefault().Value("cities"),
JArray)
Dim state As String = Nothing
If cities IsNot Nothing Then
state = CStr(cities.Where(Function(c) CStr(c("OwnerName") = "D3vil666")) _
.FirstOrDefault()("state"))
End If
I think this is a spot where VB still needs the continuation characters to handle the lines properly.

JSON.Net Deserialization error, My Class definition is wrong?

In VB.Net program I'm getting the "Cannot deserialize the current JSON array" when using JsonConvert.DeserializeObject(Of MCMusicElements)(sRB).
The JSON array I'm working with is:
[{"Key":465419,"MIK_Energy":3,"MIK_Camelot":"9B","MIK_BPM":118}]
If I delete the "[ ]" in the JSON string my program works. So, I'm assuming my Class definition for MCMusicElements is wrong in some way. I'd like to understand how to make it work without deleting the brackets from the JSON string.
Public Class MCMusicElements
Public Property Key As Integer
Public Property MIK_Energy As Integer
Public Property MIK_Camelot As String
Public Property MIK_BPM As Integer
End Class
Dim oResult = JsonConvert.DeserializeObject(Of MCMusicElements)(sRB)
dtDataTable.Rows(index).Item(1) = oResult.MIK_Energy
dtDataTable.Rows(index).Item(2) = oResult.MIK_Camelot
dtDataTable.Rows(index).Item(3) = oResult.MIK_BPM
you have to use list of objects, not an object
Dim oResult = JsonConvert.DeserializeObject(Of List(Of MCMusicElements))(sRB)
dtDataTable.Rows(index).Item(1) = oResult(0).MIK_Energy

json key with array of values - how to parse

This is the json data I am trying to parse. (I did trim the imagedata down for example purposes)
{"imageData":["SUkqAORlAACGniG0JCHeSTV9icwWxF+N9AwzcsTDlLu+PeYCgeZXAP//","sfsdfsdyfhh2h43h8ysdfsdnvjknjfdsfdsf"]}
Any idea on how to parse it into a strongly typed class in .NET?
I am using the newtonsoft.json
I tried the following
Public Class DAFGImages
Public imageData As List(Of String)
End Class
Dim DAFGImages As List(Of DAFGImages) = Newtonsoft.Json.JsonConvert.DeserializeObject(json, GetType(List(Of DAFGImages)))
Your class already contains a List of string, so you dont need a list of DAFGImages too. I would change the class member to a property:
Public Class DAFGImages
Public Property imageData As List(Of String)
End Class
Then:
Dim jstr = ... from wherever
Dim myImgs = Newtonsoft.Json.JsonConvert.DeserializeObject(Of DAFGImages)(jstr)
myImgs.ImageData will contain the 2 elements.

VB.Net Need some tips for using JavaScriptSerializer to Deserialize JSON string

First question asked here, it is nice to be part of a coding community!
Currently I am retrieving a JSON string from an API and the response is as follows:
[{"playerId":37067559,"championId":78,"championLevel":5,"championPoints":93023,"lastPlayTime":1454133232000,"championPointsSinceLastLevel":71423,"championPointsUntilNextLevel":0},{"playerId":37067559,"championId":105,"championLevel":5,"championPoints":39025,"lastPlayTime":1454130615000,"championPointsSinceLastLevel":17425,"championPointsUntilNextLevel":0},{"playerId":37067559,"championId":81,"championLevel":5,"championPoints":37068,"lastPlayTime":1454273384000,"championPointsSinceLastLevel":15468,"championPointsUntilNextLevel":0}]
I set the string to be "response2"
Dim response2 As String = serviceRequest.DownloadString(New Uri(Mastery))
However in using the JavaScriptSerializer the code exits my console
Dim jss As New JavaScriptSerializer()
Dim model As MyModel = jss.Deserialize(Of MyModel)(response2)
Console.Write(model.championId(0))
Console.ReadLine()
I set the model for the Deserializer aswell
Public Class MyModel
Public Property playerId() As String
Public Property championId() As String
Public Property championPoints() As String
Public Property lastPlayTime() As String
Public Property championPointsSinceLastLevel() As String
Public Property championPointsUntilNextLevel() As String
End Class
However on startup the console exits itself. I'm not sure if I'm supposed to use model.championId(0) aswell, I assume to becuase there is more than one set of championId.
You need array of MyModel to hold the serialized objects
Try this (comment in code):
Dim jss As New JavaScriptSerializer()
' use model() to hold aray of MyModel
Dim model() As MyModel = jss.Deserialize(Of MyModel())(response2)
'As model is now array of MyModel you should use model(0), model(1) etc...
Console.Write(model(0).championId())

Generation of dynamic class from XML to JSON

What I am trying to achieve is convert XML to a JSON object. Currently I am doing it like this:
Public Class Person
Public Property Name As String
' other properties here'
End Class
Dim doc As XmlDocument
doc.LoadXml(arg_strXml)
Dim jsonValue As String = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JsonConvert.DeserializeObject(Of Person)(jsonValue)
Dim firstName As String = jsonObject.Name
However the issue is the retrieved XML, and thus the deserialized JSON object has different fields/properties/elements depending on the correct function. It would be a nightmare to have a class for each possible XML.
Is there a way round not having to create a specific class (Person in this case) for each deserialize?
You can deserialze/parse your JSON string into Newtonsoft's JObject. Then you can access the properties like Dictionary(Of String, String), for example :
Dim arg_strXml = "<Person><Name>foo</Name></Person>"
Dim doc = New XmlDocument()
doc.LoadXml(arg_strXml)
Dim jsonValue = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JObject.Parse(jsonValue)
Console.WriteLine(jsonObject("Person")("Name"))
dotnetfiddle demo
output :
foo