VB.NET: Deserialize nested, different Object - json

I want to deserialize a few VB.Net objects. Two classes of AllgTyp inherit here and are packed in a list.
If it were not a list, but non-nested objects, a simple JSON converter (how to deserialize JSON into IEnumerable<BaseType> with Newtonsoft JSON.NET) would be a solution.
But how do I resolve the whole thing so that the nesting is deserialized?
Imports Newtonsoft.Json
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Install Newtonsoft over "View" > "Other Windows" > "Package Manager Console" -> type in:
'Install-Package Newtonsoft.Json
Dim output As String = JsonConvert.SerializeObject(testemal(), Formatting.Indented)
Dim deserializedProduct As List(Of AllgTyp) = JsonConvert.DeserializeObject(Of List(Of AllgTyp))(output)
End Sub
Private Function testemal() As List(Of AllgTyp)
Dim lstMarken As New List(Of AllgTyp)
Dim textmarken1 As New Verschachtelung("vorbriefanrede", "C:\tmp2\anrede.docx", "sdfs")
lstMarken.Add(textmarken1)
Dim textmarken2 As New Verschachtelung("inhalt", "C:\tmp2\DatMeinInhalt.docx", "sdfsdfinInhalt")
lstMarken.Add(textmarken2)
Dim aa As New Textmarke("datum", "24.02.2020")
textmarken2.Verschachtelung.Add(aa)
Dim ab As New Textmarke("Empfaenger", "isjdfosdfjosdjf")
textmarken2.Verschachtelung.Add(ab)
Dim c2 As New Verschachtelung("mbnmbnmbnm", "C:\tmp2\DatMeinInhalt.docx", "sfssfachinsdfsdfhalt1")
textmarken2.Verschachtelung.Add(c2)
Dim c3 As New Verschachtelung("sdfsfsfsss", "fsdf")
c2.Verschachtelung.Add(c3)
Dim c4 As New Verschachtelung("sdfsdf", "vo_fachinhalt3")
c3.Verschachtelung.Add(c4)
Dim c5 As New Verschachtelung("cbvcbcbcv", "vo_fachinhalt4")
c4.Verschachtelung.Add(c5)
Dim c6 As New Verschachtelung("vcbcvbcbcbc", "vo_fachinhalt5")
c4.Verschachtelung.Add(c6)
Return lstMarken
End Function
End Class
Public Class AllgTyp
Sub New()
End Sub
End Class
Public Class Textmarke
Inherits AllgTyp
Public textmarkenname As String
Public wert As String
Sub New()
End Sub
Sub New(textmarkenname As String, wert As String)
Me.textmarkenname = textmarkenname
Me.wert = wert
End Sub
End Class
Public Class Verschachtelung
Inherits AllgTyp
Public quellDatei As String
Public quelleBereich As String
Public zielBereich As String
Public Verschachtelung As New List(Of AllgTyp)
Sub New()
End Sub
Sub New(zielBereich As String, quelleBereich As String)
Me.New(zielBereich, Nothing, quelleBereich)
End Sub
Sub New(zielBereich As String, quellDatei As String, quelleBereich As String)
Me.zielBereich = zielBereich
Me.quellDatei = quellDatei
Me.quelleBereich = quelleBereich
End Sub
End Class

Related

How to deserialize json in VB.Net

I have a JSON that I want to deserialize.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim client As New RestClient(BaseUrl)
Dim Respons As Object
client.Authenticator = OAuth1Authenticator.ForProtectedResource(PublicKey, PrivateKey, Token, TokenSecret)
Dim request As New RestRequest("xml/devices/list", Method.Get)
Respons = client.Execute(request)
Console.WriteLine(Respons.Content)
Console.ReadLine()
Dim request2 As New RestRequest("json/sensor/history?id=1556402310&IncludeUnit=1&InculdeHumanReadableDate=1", Method.Get)
Respons = client.Execute(request2)
Console.WriteLine(Respons.Content)
Console.ReadLine()
End Sub
So the JSON is in Respons, but I haven't a clue how to deserialize it
Have not done anything because I don't know how.
This is how the JSON looks like
Something like this:
Public Class Sensor_class
Public Property thing As Integer
Public Property thing2 As Object
Public Property results As Result()
End Class
Dim o as Sensor_class
o = JsonConvert.DeserializeObject(Of Sensor_class)(Respons.Content)

'The node must be of type 'JsonObject'.'

I'm trying to parse this Json
With the code:
Dim streamData As Stream = Nothing
Using http As New HttpClient
Dim url As String = "https://api.hotbit.io/api/v1/market.deals?market=KIBA/USDT&limit=150&last_id=1521100930&api_key=44812d8f-66d3-01c0-94c3b29305040b03&sign=98EEC3D69D3F70F9BDFED901984B2AA4"
Dim t As Task(Of Stream) = http.GetStreamAsync(url)
streamData = t.Result
End Using
Dim jsonResponse As JsonNode = JsonNode.Parse(streamData)
Dim result As JsonObject = jsonResponse("result").AsObject
Dim c As String = String.Empty
For Each kvp In result.AsEnumerable
c &= kvp.Value("price").ToString & vbCr
Next
RichTextBox1.Text = c
End Sub
but I keep getting the error at debug
The node must be of type 'JsonObject'.'
on the line
Dim result As JsonObject = jsonResponse("result").AsObject
How it comes it gives an error If I'm already trying to parse it as a Jsonobject?
Thanks
Give a go at this..
Paste this into a new class file:
Namespace HotBit
Partial Public Class TradeCollection
<JsonProperty("error")>
Public Property [Error] As Object
<JsonProperty("result")>
Public Property Result As List(Of Result)
<JsonProperty("id")>
Public Property Id As Long
End Class
Partial Public Class Result
<JsonProperty("id")>
Public Property Id As Long
<JsonProperty("time")>
Public Property Time As Long
<JsonProperty("price")>
Public Property Price As String
<JsonProperty("amount")>
<JsonConverter(GetType(ParseStringConverter))>
Public Property Amount As Long
<JsonProperty("type")>
Public Property Type As TypeEnum
End Class
Public Enum TypeEnum
Buy
Sell
End Enum
Partial Public Class TradeCollection
Public Shared Function FromJson(ByVal json As String) As TradeCollection
Return JsonConvert.DeserializeObject(Of TradeCollection)(json, Settings)
End Function
End Class
Public Module Serialize
<Extension()>
Public Function ToJson(ByVal self As TradeCollection) As String
Return JsonConvert.SerializeObject(self, Settings)
End Function
End Module
Friend Module Converter
Public ReadOnly Settings As JsonSerializerSettings = New JsonSerializerSettings With {
.MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
.DateParseHandling = DateParseHandling.None
}
End Module
Friend Class ParseStringConverter
Inherits JsonConverter
Public Overrides Function CanConvert(ByVal t As Type) As Boolean
Return t Is GetType(Long) OrElse t Is GetType(Long?)
End Function
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal t As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
If reader.TokenType = JsonToken.Null Then Return Nothing
Dim value = serializer.Deserialize(Of String)(reader)
Dim l As Long
If Long.TryParse(value, l) Then
Return l
End If
Throw New Exception("Cannot unmarshal type long")
End Function
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal untypedValue As Object, ByVal serializer As JsonSerializer)
If untypedValue Is Nothing Then
serializer.Serialize(writer, Nothing)
Return
End If
Dim value = CLng(untypedValue)
serializer.Serialize(writer, value.ToString())
Return
End Sub
Public Shared ReadOnly Singleton As ParseStringConverter = New ParseStringConverter()
End Class
Friend Class TypeEnumConverter
Inherits JsonConverter
Public Overrides Function CanConvert(ByVal t As Type) As Boolean
Return t Is GetType(TypeEnum) OrElse t Is GetType(TypeEnum?)
End Function
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal t As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
If reader.TokenType = JsonToken.Null Then Return Nothing
Dim value = serializer.Deserialize(Of String)(reader)
Select Case value
Case "buy"
Return TypeEnum.Buy
Case "sell"
Return TypeEnum.Sell
End Select
Throw New Exception("Cannot unmarshal type TypeEnum")
End Function
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal untypedValue As Object, ByVal serializer As JsonSerializer)
If untypedValue Is Nothing Then
serializer.Serialize(writer, Nothing)
Return
End If
Dim value = CType(untypedValue, TypeEnum)
Select Case value
Case TypeEnum.Buy
serializer.Serialize(writer, "buy")
Return
Case TypeEnum.Sell
serializer.Serialize(writer, "sell")
Return
End Select
Throw New Exception("Cannot marshal type TypeEnum")
End Sub
Public Shared ReadOnly Singleton As TypeEnumConverter = New TypeEnumConverter()
End Class
End Namespace
Then install Newtonsoft (if not already) and Imports it
Then Imports HotBit (or if you changed the Namespace of the "paste this" above, Imports that new namespace
Then do your request and query the result e.g.:
Sub Main(args As String())
Dim s = New WebClient().DownloadString("https://api.hotbit.io/api/v1/market.deals?market=KIBA/USDT&limit=150&last_id=1521100930&api_key=44812d8f-66d3-01c0-94c3b29305040b03&sign=98EEC3D69D3F70F9BDFED901984B2AA4")
Dim tc = TradeCollection.FromJson(s)
Dim prices = String.Join(","c, tc.Result.Select(Function(r) r.Price))
End Sub

JSon Serialize complex object with datatable inside

I have this kind of object:
Public Class ClasseProva
Inherits RM_Base
Public Sub New()
Me.NomeTabella = "ClasseProva"
End Sub
Private m_AZI_ID As Integer
Public Property AZI_ID() As Integer
Get
Return m_AZI_ID
End Get
Set(ByVal value As Integer)
m_AZI_ID = value
End Set
End Property
Private m_dtPROGETTI As DataTable
Public Function ProgettiRO() As DataTable
Return m_dtPROGETTI
End Function
Public Sub ProgettiWO(value As DataTable)
m_dtPROGETTI = value
End Sub
End Class
So if in my object there is no datatable, I know how to serialize using Json and use serialized object as cookie. So in this way I have
public ClasseProva CookieClasseProva
{
get
{
try
{
string myObjectJson = Request.Cookies["CookieClasseProva"].Value;
return JsonConvert.DeserializeObject<ClasseProva>(myObjectJson);
}
catch { return null; }
}
set
{
string myObjectJson = JsonConvert.SerializeObject(value);
var cookie = new HttpCookie("CookieClasseProva", myObjectJson)
{
Expires = DateTime.Now.AddYears(1)
};
Response.Cookies.Add(cookie);
}
}
But after I added datatable, serialization function doesn't serialize datatable.
EDIT:
I don't know how attach a project. But now I'm copying Class of my BL project
Public Class Class1
Private m_intValue As Integer
Public Property MyIntValue() As Integer
Get
Return m_intValue
End Get
Set(ByVal value As Integer)
m_intValue = value
End Set
End Property
Private m_dtValue As DataTable
Public Property MyDatatable() As DataTable
Get
Return m_dtValue
End Get
Set(value As DataTable)
m_dtValue = value
End Set
End Property
End Class
and code section of a simple page
Imports Newtonsoft.Json
Imports DatatableSerializationBL
Public Class _Default
Inherits Page
Public Property CookieUtente() As Class1
Get
Try
Dim myObjectJson As String = Request.Cookies("CookieUtente").Value
Return JsonConvert.DeserializeObject(Of Class1)(myObjectJson)
Catch
Return Nothing
End Try
End Get
Set(value As Class1)
Dim myObjectJson As String = JsonConvert.SerializeObject(value)
Dim cookie = New HttpCookie("CookieUtente", myObjectJson)
Response.Cookies.Add(cookie)
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim c As New Class1
c.MyIntValue = 1
c.MyDatatable = New DataTable
c.MyDatatable.NewRow()
CookieUtente = c
Console.WriteLine(CookieUtente.MyDatatable.Rows.Count)
End Sub
End Class
So in the design page , I print rows.count value and it prints 0
ROWS : <%= CookieUtente.MyDatatable.Rows.Count%>

Error While serializing object to json format using JsonConvert.SerializeObject function

I have a method to serialize object to json format. the object contains nested objects and lists. but i face this error :
Error getting value from 'Length' on 'Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter'.
Dim serilaize As New JsonSerializerSettings()
With serilaize
.PreserveReferencesHandling = PreserveReferencesHandling.Objects
End With
Dim strProgram As String = JsonConvert.SerializeObject(ProgramObject, Formatting.Indented, serilaize)
Any help please !
Thanks
This works:
Module Module1
Sub Main()
Dim ProgramObject = New TestObject()
ProgramObject.Items = New List(Of String)
ProgramObject.Items.Add("testitem")
Dim serialize As New Newtonsoft.Json.JsonSerializerSettings()
With serialize.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects
Dim strProgram As String = Newtonsoft.Json.JsonConvert.SerializeObject(ProgramObject, Newtonsoft.Json.Formatting.Indented, serialize)
End With
End Sub
End Module
TestObject looks like this:
Public Class TestObject
Property Items As List(Of String)
End Class

WebService Asp.Net Json not serialize a List(Of Class)

after a lot of time searching here and in the web, i'm posting my problem and my code for yours teach me how i do this works.
The problem is that the Json not serialize listUsuarios, when i use JavaScriptSerializer the return is "{}" and when i use JsonConvert.SerializeObject the return is "False".
Sorry for my bad english.
Here is the code...
USUARIOS.VB
Imports Microsoft.VisualBasic
Public Class Usuarios
Private _Codigo As Long
Private _Nome As String
Private _Telefone As String
Public Property Codigo As Integer
Get
Return _Codigo
End Get
Set(ByVal value As Integer)
_Codigo = value
End Set
End Property
Public Property Nome() As String
Get
Return _Nome
End Get
Set(ByVal value As String)
_Nome = value
End Set
End Property
Public Property Telefone() As String
Get
Return _Telefone
End Get
Set(ByVal value As String)
_Telefone = value
End Set
End Property
End Class
Public Class ListUsuarios
Private listUsuarios As List(Of Usuarios)
Public Sub New()
listUsuarios = New List(Of Usuarios)
End Sub
Public Sub AddItem(ByVal usuario As Usuarios)
listUsuarios.Add(usuario)
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
Public Function Item(ByVal Index As Integer) As Usuarios
Return CType(listUsuarios.Item(Index), Usuarios)
End Function
Public Function Count() As Integer
Return listUsuarios.Count
End Function
End Class
ANDROID.VB
Imports Newtonsoft.Json
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Xml
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class Android
Inherits System.Web.Services.WebService
Dim Dt As DataTable
Dim Da As New OleDbDataAdapter
Dim Cmd As New OleDbCommand
Dim cn As New OleDb.OleDbConnection
<WebMethod()> _
Public Function Android(query As String) As String
Dim listUsuario As ListUsuarios = carregaDadosAccess(query)
Return retornaDadosJSON(listUsuario)
End Function
Private Function getConexaoDB() As OleDbConnection
Try
cn.ConnectionString = ConfigurationManager.ConnectionStrings("MyLocalAccess").ConnectionString
cn.Open()
Return cn
Catch ex As Exception
Throw ex
End Try
End Function
Private Sub closeConexaoDB(ByVal cn As OleDbConnection)
Try
If cn.State = ConnectionState.Open Then
cn.Close()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Private Function carregaDadosAccess(selectCommmand As String) As ListUsuarios
Dim usuario As Usuarios = Nothing
Dim listUsuario As New ListUsuarios
Dim i As Long = 0
Try
cn = getConexaoDB()
Dim da As New OleDb.OleDbDataAdapter(selectCommmand, cn)
Dim dt As New DataTable
Dim arrImage() As Byte = Nothing
Dim myMS As New IO.MemoryStream
da.Fill(dt)
If dt.Rows.Count > 0 Then
Do
usuario = New Usuarios
usuario.Codigo = dt.Rows(i).Item("key-codigo")
usuario.Nome = dt.Rows(i).Item("dad-descri")
usuario.Telefone = dt.Rows(i).Item("dad-telefo")
listUsuario.AddItem(usuario)
i = i + 1
If i = dt.Rows.Count Then Exit Do
Loop
Else
listUsuario = Nothing
End If
Catch ex As Exception
Throw ex
Finally
closeConexaoDB(cn)
End Try
Return listUsuario
End Function
Private Function retornaDadosJSON(listUsuario As ListUsuarios) As String
'Json serializer do prĂ³prio .net
'Dim JsonSerializer As New JavaScriptSerializer
'Return JsonSerializer.Serialize(listUsuario)
'Json serializer James Newton-King
Dim JsonSerializer As String = ""
Return JsonSerializer = JsonConvert.SerializeObject(listUsuario)
End Function
End Class
The first problem is you are returning a value that compares an empty string with the serialized json string and since the json serialized string is not empty. This is where the result of "False" is coming from.
You can fix that problem by changing the method to:
Private Function retornaDadosJSON(listUsuario As ListUsuarios) As String
Return JsonConvert.SerializeObject(listUsuario)
End Function
You can prevent this type of issue in the future by adding the following directives to the top of each file:
Option Explicit On
Option Strict On
or by setting the corresponding values in the project's Compile property page (you can also set these to default values for new projects in Visual Studio's Tools > Options > Projects and Solutions > VB Default).
Option Strict On would have prevented that code from compiling. It would also show you that there is a data type difference between _Codigo and Codigo (one is Long the other is Integer).
The second problem is that ListUsuarios isn't defined well for what you are trying to do with it. It would be much better to inherit from List(Of Usuarios) than your current design.
Changing to the following class will both reduce the code and ensure the data is serialized correctly:
Public Class ListUsuarios
Inherits List(Of Usuarios)
Public Sub AddItem(ByVal usuario As Usuarios)
Me.Add(usuario)
End Sub
End Class