I've had no trouble writing a non-List object to XML, it reads and writes as expected. But making a List object write to XML is throwing my entire export/import process against the wall, and I can't figure out why.
Object is built off of this class:
Public Class PowerArray
'Array that stores Powers for active character
Public Name As String
Public PRating As Integer
Public Action As String
Public Cost As Integer
Public PoolNone As String
Public Pool1 As String
Public Pool2 As String
Public Range As String
Public Duration As String
Public Tags As New List(Of Object)
Public Desc As String
End Class
Object created from the Class is:
Public Shared Property CharPowers As New List(Of PowerArray)
As an example, I can write the Object "CharCore" (as defined off of class "Character", and which isn't a list) to XML just fine.
If I try to write CharPowers as a populated List to XML, it throws an error from this:
Dim writer As New System.Xml.Serialization.XmlSerializer(GetType(frmMain.PowerArray))
Dim file As New System.IO.StreamWriter("c:\temp\" "PowerTest.PWR")
writer.Serialize(file, frmMain.GVar.CharPowers)
file.Close()
-with error "InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[NICO_SP_v2.frmMain PowerArray]' to type 'PowerArray'."
I'm not sure what makes a List different here. Any help would be appreciated.
CodePudding user response:
An Xml document must have a root element, i.e. cannot just have a bunch of elements at the top level. So instead make a class to hold the list of PowerArray
Make your classes like this
Imports System.IO
Imports System.Xml.Serialization
<XmlRoot>
Public Class PowerArrays
<XmlElement("PowerArray")>
Public Property List As List(Of PowerArray)
End Class
Public Class PowerArray ' unchanged
'Array that stores Powers for active character
Public Name As String
Public PRating As Integer
Public Action As String
Public Cost As Integer
Public PoolNone As String
Public Pool1 As String
Public Pool2 As String
Public Range As String
Public Duration As String
Public Tags As New List(Of Object)
Public Desc As String
End Class
And serialize the root instead
Dim powers = New PowerArrays() With {.List = frmMain.GVar.CharPowers.ToList()}
Dim serializer As New XmlSerializer(GetType(PowerArrays))
Using writer As New StreamWriter($"c:\temp\{PowerTest.PWR}")
serializer.Serialize(writer, powers)
End Using
Your Xml should result in
<?xml version="1.0" encoding="utf-8"?>
<PowerArrays>
<PowerArray>
<Name>foo</Name>
...
</PowerArray>
<PowerArray>
<Name>bar</Name>
...
</PowerArray>
</PowerArrays>
Deserialize in reverse
Dim powers = New PowerArrays()
Dim serializer As New XmlSerializer(GetType(PowerArrays))
Using reader As New StreamReader($"c:\temp\{PowerTest.PWR}")
powers = DirectCast(serializer.Deserialize(reader), PowerArrays)
End Using