InvalidOperationException on GetType - vb.net

I try to serialize a Class in VB using XMLSerializer.
But when I call GetType for my Class I got a InvalidOperationException error.
Dim Playlist_serialize As New XmlSerializer(p.GetType)
Here is my class :
Public Class Playlist
Private p_name As String
Private p_elements As List(Of Playlist_element)
Sub New()
p_elements = New List(Of Playlist_element)
End Sub
Public Property Name() As String
Get
Name = p_name
End Get
Set(value As String)
p_name = value
End Set
End Property
Public Property Elements() As List(Of Playlist_element)
Get
Elements = p_elements
End Get
Set(value As List(Of Playlist_element))
p_elements = value
End Set
End Property
Here is my Playlist_element :
Public Class Playlist_element
Private p_Name As String
Private p_Type As String
Private p_Genre As String
Public Property Name() As String
Get
Name = p_Name
End Get
Set(value As String)
p_Name = value
End Set
End Property
Public Property Type() As String
Get
Type = p_Type
End Get
Set(value As String)
p_Type = value
End Set
End Property
Public Property Genre() As String
Get
Genre = p_Genre
End Get
Set(value As String)
p_Genre = value
End Set
End Property
Sub New(ByVal name As String, ByVal type As String, ByVal genre As String)
Me.Name = name
Me.Genre = genre
Me.Type = Type
End Sub
End Class

There are several issues with the way Playlist_element is coded. First your property getters are wrong. They need to return the backing field:
Public Property Name() As String
Get
' this does nothing:
'Name = p_Name
Return p_Name
End Get
Set(value As String)
p_Name = value
End Set
End Property
Next, I would not use Type as a property name even if you can. If you drill into the inner exception and view the message, it tells you that it cannot serialize PlayList_element because it does not have a simple constructor. All serializers require this because they do not know how to use:
Sub New(ByVal name As String, ByVal type As String, ByVal genre As String)
p_Name = name
p_Genre = genre
p_Type = type
End Sub
' add:
Public Sub New()
End Sub
It should work fine. I should note that as of VS2010, you can use auto-implemented properties and skip a lot of that code:
Public Class Element
Public Property Name() As String
Public Property Type() As String
Public Property Genre() As String
Sub New(name As String, type As String, genre As String)
_Name = name
_Genre = genre
_Type = type
End Sub
Public Sub New()
End Sub
End Class
VS provides a "hidden" backing field as with _Name, _Genre etc.

Related

Looping through a class list with multiple items

I have a class containing the following:
Public Class ConflictClass
Public Sub New(ByVal emp As String, ByVal cli As String, ByVal serv As String, ByVal tme As String, ByVal dte As String, ByVal dy As String)
_emp = emp
_cli = cli
_serv = serv
_tme = tme
_dte = dte
_dy = dy
End Sub
Private Shared _emp As String
Public Shared Property employee As String
Get
Return _emp
End Get
Set(value As String)
_emp = value.ToString.Trim
End Set
End Property
Private Shared _cli As String
Public Shared Property client As String
Get
Return _cli
End Get
Set(value As String)
_cli = value.ToString.Trim
End Set
End Property
Private Shared _serv As String
Public Shared Property service As String
Get
Return _serv
End Get
Set(value As String)
_serv = value.ToString.Trim
End Set
End Property
Private Shared _tme As String
Public Shared Property appttime As String
Get
Return _tme
End Get
Set(value As String)
_tme = value.ToString.Trim
End Set
End Property
Private Shared _dte As String
Public Shared Property apptdate As String
Get
Return _dte
End Get
Set(value As String)
_dte = value.ToString.Trim
End Set
End Property
Private Shared _dy As String
Public Shared Property apptday As String
Get
Return _dy
End Get
Set(value As String)
_dy = value.ToString.Trim
End Set
End Property
End Class
It is filled on one Windows form and I am trying to pass a list of this type to another form, loop through it (or use it as a data source) and fill a grid. I am struggling to find an example of this. Can someone help?

Getting a property from the instantiator class

Not an experienced programmer, so probably not a hard question.
Developing a small application in VB.net in WPF.
I made 3 classes, EngineeringObject<==Inherits==PartOfInstallation<==Inherits==SensorActor
In the class SensorActor I'm trying to get a property of PartOfInstallation with the function MyBase.Name. But this goes directly to EngineeringObject. How do I solve this?
Public Class EngineeringObject
''Private declarations, alleen objecten die erven kunnen hieraan, of dmv van getters en setters
'Name of part
Private sName As String = "Naam"
'81346 Id's
Private sSystemId As String = "Functie" 'VentilationSystem, Pumpsystem
Private sLocationId As String = "Locatie" 'Room 0.0
Private sObjectId As String = "Object" 'Fan, Pump
'General
Private sPartNumber As String
Private sLinkToDatasheet As String
'Property's
Public Property Name() As String
Get
Return sName
End Get
Set(ByVal value As String)
sName = value
End Set
End Property
Public Property SystemId() As String
Get
Return sSystemId
End Get
Set(ByVal value As String)
sSystemId = value
End Set
End Property
Public Property PartNumber() As String
Get
Return sPartNumber
End Get
Set(ByVal value As String)
sPartNumber = value
End Set
End Property
Public Property LinkToDatasheet() As String
Get
Return sLinkToDatasheet
End Get
Set(ByVal value As String)
sLinkToDatasheet = value
End Set
End Property
Public Sub New()
End Sub
End Class
Public Class PartOfInstallation
Inherits EngineeringObject
'src: https://stackoverflow.com/questions/21308881/parent-creating-child-object
'src: https://stackoverflow.com/questions/16244548/how-to-create-a-list-of-parent-objects-where-each-parent-can-have-a-list-of-chil
Private lSensorActor As New List(Of SensorActor)
Public Function GetSensorActor()
Return Me.lSensorActor
End Function
Public Sub CreateSensorActor()
lSensorActor.Add(New SensorActor)
End Sub
End Class
Public Class SensorActor
Inherits PartOfInstallation
Dim sMyPartOfInstallation As String
Public Property MyPartOfInstallation As String
Get
Return sMyPartOfInstallation
End Get
Set(value As String)
sMyPartOfInstallation = MyBase.Name
End Set
End Property
End Class
If I understand it correctly, based on your comments, you want every SensorActor instantiated within a PartOfInstallation instance to get the same name as that instance.
If so, then just add a second constructor to your SensorActor class allowing you to pass a name for it as well:
Public Class SensorActor
Inherits PartOfInstallation
...your code...
Public Sub New() 'Empty constructor, for if/when you don't want to set the name immediately.
End Sub
Public Sub New(ByVal Name As String)
Me.Name = Name
End Sub
End Class
Now in your PartOfInstallation class you can do:
Public Sub CreateSensorActor()
lSensorActor.Add(New SensorActor(Me.Name)) 'Here, "Me" refers to the current PartOfInstallation instance.
End Sub
Alternatively you can make the SensorActor constructor take a PartOfInstallation instance instead, allowing you to copy any properties you like:
Public Class SensorActor
Inherits PartOfInstallation
...your code...
Public Sub New()
End Sub
Public Sub New(ByVal BasedOnPOI As PartOfInstallation)
Me.Name = BasedOnPOI.Name
End Sub
End Class
Thus making the code in the PartOfInstallation class:
Public Sub CreateSensorActor()
lSensorActor.Add(New SensorActor(Me))
End Sub
Read more about constructors: Object Lifetime: How Objects Are Created and Destroyed (Visual Basic) | Microsoft Docs
The result below, if there's room for improvement... always welcome.
SensorActor
Public Class SensorActor
Inherits PartOfInstallation
Dim sTemp As String
Public Overloads Property SystemId() As String
Get
Return Me.sSystemId
End Get
Set(ByVal value As String)
Me.sSystemId = sTemp + "." + value
End Set
End Property
Public Sub New(ByVal BasedOnPOI As PartOfInstallation)
sTemp = BasedOnPOI.SystemId
End Sub
End Class
PartOfInstallation
Public Class PartOfInstallation
Inherits EngineeringObject
'src: https://stackoverflow.com/questions/21308881/parent-creating-child-object
'src: https://stackoverflow.com/questions/16244548/how-to-create-a-list-of-parent-objects-where-each-parent-can-have-a-list-of-chil
Private lSensorActor As New List(Of SensorActor)
Public Function GetSensorActor()
Return Me.lSensorActor
End Function
Public Sub CreateSensorActor()
lSensorActor.Add(New SensorActor(Me))
End Sub
End Class
EngineeringObject
Public Class EngineeringObject
''Private declarations, alleen objecten die erven kunnen hieraan, of dmv van getters en setters
'Name of part
Private sName As String = "Naam"
'81346 Id's
Friend sSystemId As String = "Functie" 'VentilationSystem, Pumpsystem
Private sLocationId As String = "Locatie" 'Room 0.0
Private sObjectId As String = "Object" 'Fan, Pump
'General
Private sPartNumber As String
Private sLinkToDatasheet As String
'Property's
Public Property Name() As String
Get
Return sName
End Get
Set(ByVal value As String)
sName = value
End Set
End Property
Public Property SystemId() As String
Get
Return sSystemId
End Get
Set(ByVal value As String)
sSystemId = "=" + value
End Set
End Property
Public Property PartNumber() As String
Get
Return sPartNumber
End Get
Set(ByVal value As String)
sPartNumber = value
End Set
End Property
Public Property LinkToDatasheet() As String
Get
Return sLinkToDatasheet
End Get
Set(ByVal value As String)
sLinkToDatasheet = value
End Set
End Property
Public Sub New()
End Sub
End Class

How to get all json values with newtonsoft

I'm having a hard time getting through all the JSON values ​​of a string, can anyone help me?
I'm only getting a single value, where am I going wrong?
My codes
Dim address As String = "http://wsloterias.azurewebsites.net/api/sorteio/getresultado/1"
Dim client As WebClient = New WebClient()
Dim reader As StreamReader = New StreamReader(client.OpenRead(address))
Dim json = (reader.ReadToEnd)
Dim objs As RootObject = JsonConvert.DeserializeObject(Of RootObject)(json)
Dim objsSorteio As Sorteio = JsonConvert.DeserializeObject(Of Sorteio)(json)
For Each nums In objsSorteio.Premios
MsgBox(nums.ToString)
Next
Classes
Public Class Premio
Public Property Faixa() As String
Get
Return m_Faixa
End Get
Set(value As String)
m_Faixa = Value
End Set
End Property
Private m_Faixa As String
Public Property NumeroGanhadores() As Integer
Get
Return m_NumeroGanhadores
End Get
Set(value As Integer)
m_NumeroGanhadores = Value
End Set
End Property
Private m_NumeroGanhadores As Integer
Public Property Valor() As Double
Get
Return m_Valor
End Get
Set(value As Double)
m_Valor = Value
End Set
End Property
Private m_Valor As Double
End Class
Public Class Sorteio
Public Property NumSorteio() As Integer
Get
Return m_NumSorteio
End Get
Set(value As Integer)
m_NumSorteio = Value
End Set
End Property
Private m_NumSorteio As Integer
Public Property Numeros() As List(Of Integer)
Get
Return m_Numeros
End Get
Set(value As List(Of Integer))
m_Numeros = Value
End Set
End Property
Private m_Numeros As List(Of Integer)
Public Property Premios() As List(Of Premio)
Get
Return m_Premios
End Get
Set(value As List(Of Premio))
m_Premios = Value
End Set
End Property
Private m_Premios As List(Of Premio)
Public Property Ganhadores() As List(Of Object)
Get
Return m_Ganhadores
End Get
Set(value As List(Of Object))
m_Ganhadores = Value
End Set
End Property
Private m_Ganhadores As List(Of Object)
End Class
Public Class RootObject
Public Property NumeroConcurso() As Integer
Get
Return m_NumeroConcurso
End Get
Set(value As Integer)
m_NumeroConcurso = Value
End Set
End Property
Private m_NumeroConcurso As Integer
Public Property Acumulou() As Boolean
Get
Return m_Acumulou
End Get
Set(value As Boolean)
m_Acumulou = Value
End Set
End Property
Private m_Acumulou As Boolean
Public Property EstimativaPremio() As Double
Get
Return m_EstimativaPremio
End Get
Set(value As Double)
m_EstimativaPremio = Value
End Set
End Property
Private m_EstimativaPremio As Double
Public Property ValorAcumulado() As Double
Get
Return m_ValorAcumulado
End Get
Set(value As Double)
m_ValorAcumulado = Value
End Set
End Property
Private m_ValorAcumulado As Double
Public Property Data() As String
Get
Return m_Data
End Get
Set(value As String)
m_Data = Value
End Set
End Property
Private m_Data As String
Public Property RealizadoEm() As String
Get
Return m_RealizadoEm
End Get
Set(value As String)
m_RealizadoEm = Value
End Set
End Property
Private m_RealizadoEm As String
Public Property DescricaoAcumuladoOutro() As String
Get
Return m_DescricaoAcumuladoOutro
End Get
Set(value As String)
m_DescricaoAcumuladoOutro = Value
End Set
End Property
Private m_DescricaoAcumuladoOutro As String
Public Property ValorAcumuladoOutro() As Double
Get
Return m_ValorAcumuladoOutro
End Get
Set(value As Double)
m_ValorAcumuladoOutro = Value
End Set
End Property
Private m_ValorAcumuladoOutro As Double
Public Property DataProximo() As String
Get
Return m_DataProximo
End Get
Set(value As String)
m_DataProximo = Value
End Set
End Property
Private m_DataProximo As String
Public Property ValorAcumuladoEspecial() As Double
Get
Return m_ValorAcumuladoEspecial
End Get
Set(value As Double)
m_ValorAcumuladoEspecial = Value
End Set
End Property
Private m_ValorAcumuladoEspecial As Double
Public Property Arrecadacao() As Double
Get
Return m_Arrecadacao
End Get
Set(value As Double)
m_Arrecadacao = Value
End Set
End Property
Private m_Arrecadacao As Double
Public Property Sorteios() As List(Of Sorteio)
Get
Return m_Sorteios
End Get
Set(value As List(Of Sorteio))
m_Sorteios = Value
End Set
End Property
Private m_Sorteios As List(Of Sorteio)
End Class
I can not go through all the "Numeros" and also "Premios"
You are over complicating this unnecessarily.
using the URL provided the exposed json data was copied and plugged into a utility site like http://jsonutils.com/. It generated the models with auto properties. Note that it converted collections to array as apposed to Lists like you have in your classes.
Public Class Premio
Public Property Faixa As String
Public Property NumeroGanhadores As Integer
Public Property Valor As Double
End Class
Public Class Sorteio
Public Property NumSorteio As Integer
Public Property Numeros As Integer()
Public Property Premios As Premio()
Public Property Ganhadores As Object()
End Class
Public Class RootObject
Public Property NumeroConcurso As Integer
Public Property Acumulou As Boolean
Public Property EstimativaPremio As Double
Public Property ValorAcumulado As Double
Public Property Data As String
Public Property RealizadoEm As String
Public Property DescricaoAcumuladoOutro As String
Public Property ValorAcumuladoOutro As Double
Public Property DataProximo As String
Public Property ValorAcumuladoEspecial As Double
Public Property Arrecadacao As Double
Public Property Sorteios As Sorteio()
End Class
Basically the same as what you had originally with better readability. Feel free to convert tha arrays back to list if that is your preference.
The first desrialization is already giving you the necessary object. Drill into the properties in order to access the values you need.
'''other code removed for brevity
Dim objs As RootObject = JsonConvert.DeserializeObject(Of RootObject)(json)
Dim objsSorteioList As List(Of Sorteio) = objs.Sorteios.ToList()
For Each objsSorteio In objsSorteioList
For Each prems In objsSorteio.Premios
MsgBox(prems.ToString)
Next
For Each nums In objsSorteio.Numeros
MsgBox(nums.ToString)
Next
Next

vb.net No parameterless constructor defined for this object

I am download a Json libary here : http://www.pozzware.com/pozzware/Corsi/Programmazione/VB.NET/JSON%20Library.aspx
This is my class on my project :
Imports PW.JSON
Public Class Prova
Private _id As Integer
Private _name As String
Private _valido As Boolean
Private _subObject As Prova
Private _numero As Integer
Private _numeroDec As Double
Private _array() As String
Public Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Valido() As Boolean
Get
Return _valido
End Get
Set(ByVal value As Boolean)
_valido = value
End Set
End Property
Public Property SubObject() As Prova
Get
Return _subObject
End Get
Set(ByVal value As Prova)
_subObject = value
End Set
End Property
Public Property NumeroDec() As Double
Get
Return _numeroDec
End Get
Set(ByVal value As Double)
_numeroDec = value
End Set
End Property
Public Property Array() As String()
Get
Return _array
End Get
Set(ByVal value As String())
_array = value
End Set
End Property
Public Sub New(ByVal ID As Integer, ByVal Name As String)
_id = ID
_name = Name
End Sub
Public Function SomeMethod() As String
Return "Method: " & _id
End Function
End Class
And this is my code :
Sub PasteJsonExam()
Dim strJSON As String = "{""NumeroDec"": 100.34, ""Name"": ""Nome Object"", " & _
" ""Array"": [""A"", ""E"", ""I"", ""O"", ""U""], " & _
" ""SubObject"": {""NumeroDec"": 0, ""Name"": ""Nome - SubObject"", " & _
" ""Array"": null, ""SubObject"": null, ""Valido"": false, ""ID"": 2}, " & _
" ""Valido"": true, ""ID"": 1}"
Dim objprova As Prova
objprova = PW.JSON.JSONHelper.StringToObject(strJSON, GetType(Prova))
MsgBox(objprova.Name)
MsgBox(objprova.SubObject.Name)
End Sub
When i call that sub i got error :
No parameterless constructor defined for this object.
At this line :
objprova = PW.JSON.JSONHelper.StringToObject(strJSON, GetType(Prova))
I am not an professonal in VB.net so i hope someone explain for me why i got that error and how can i fix this.
Probably StringToObject method try to create an instance of Prova. It does this by calling the default(parameterless) constructor of the type.
But in the class you defined there isn't any parameterless constructor, you have only:
Public Class Prova
' Other fields and methods
Public Sub New(ByVal ID As Integer, ByVal Name As String)
_id = ID
_name = Name
End Sub
' Other fields and methods
End Class
To let the method work you need to define a parameterless constructor like:
Public Class Prova
' Other fields and methods
Public Sub New()
End Sub
Public Sub New(ByVal ID As Integer, ByVal Name As String)
_id = ID
_name = Name
End Sub
' Other fields and methods
End Class
Well i think that the library you are using is not the best choice, but, if you want to run your program you must add a default constructor (a constructor without parameter). That's because the library probably uses Reflection
This is the class with the Default Constructor:
Imports PW.JSON
Public Class Prova
Private _id As Integer
Private _name As String
Private _valido As Boolean
Private _subObject As Prova
Private _numero As Integer
Private _numeroDec As Double
Private _array() As String
Public Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Valido() As Boolean
Get
Return _valido
End Get
Set(ByVal value As Boolean)
_valido = value
End Set
End Property
Public Property SubObject() As Prova
Get
Return _subObject
End Get
Set(ByVal value As Prova)
_subObject = value
End Set
End Property
Public Property NumeroDec() As Double
Get
Return _numeroDec
End Get
Set(ByVal value As Double)
_numeroDec = value
End Set
End Property
Public Property Array() As String()
Get
Return _array
End Get
Set(ByVal value As String())
_array = value
End Set
End Property
' This is the default constructor the library should need'
Public Sub New()
End Sub
Public Sub New(ByVal ID As Integer, ByVal Name As String)
_id = ID
_name = Name
End Sub
Public Function SomeMethod() As String
Return "Method: " & _id
End Function
End Class

Class with a list of class in VB

I am trying to write a DLL that will accept an custom input with a nested list(of T)
I created 2 classes, a Main Class ClassPolyPoints and the nested Class classEF
I am getting an error when trying to pass the list(of classEF) object into the ClassPolyPoints object.
Dim TMP_effPoints As New List(Of classEF)
For i = 0 to 10
TMP_effPoints.Add(New classEff(
i,
i*0.125
))
Next
Dim tmpClass As New ClassPolyPoints(9.8765, TMP_effPoints)
Class that contains the nested list(of classEF)
Public Class ClassPolyPoints
Sub New(ByVal x_P0 As Double,
ByVal x_EffPoints As List(Of classEF))
_P0 = x_P0
With _effPoints
For Each a In x_EffPoints
.Add(New classEFF(
a.ID,
a.Eff
))
Next
End With
End Sub
Private _effPoints As List(Of classEff)
Public Property effPoints() As List(Of classEff)
Get
Return _effPoints
End Get
Set(ByVal value As List(Of classEff))
_effPoints = value
End Set
End Property
Private _P0 As Double
Public Property P0() As Double
Get
Return _P0
End Get
Set(ByVal value As Double)
_P0 = value
End Set
End Property
End Class
The nested class
Public Class classEF
Sub New(X_ID As Integer, X_Eff As Double)
_ID = X_ID
_Eff = X_Eff
End Sub
Private _ID As Integer
Public Property ID() As Integer
Get
Return _ID
End Get
Set(ByVal value As Integer)
_ID = value
End Set
End Property
Private _Eff As Double
Public Property Eff() As Double
Get
Return _Eff
End Get
Set(ByVal value As Double)
_Eff = value
End Set
End Property
End Class
You don't need to loop here just assign the list.
Public Class ClassPolyPoints
Sub New(ByVal x_P0 As Double,
ByVal x_EffPoints As List(Of classEF))
Me._P0 = x_P0
Me.effPoints = x_EffPoints
End Sub
'''
The issue is that you forgotten to create an istance of _effPoints before trying to add to the list new elements of class classEF:
That is in class ClassPolyPoints, you have to change the following declaration:
Private _effPoints As List(Of classEff)
into this:
Private _effPoints As New List(Of classEF)