XMLSerialization of an object

K

Klaus Jensen

Hi!

This has been bugging me for days now...

I need to xmlserialize an object which contains a
collection/hashtable/array/whatever of childobjects.

-ParentObject
---Hashtable/Array/Collection
-----ChildObject
-----ChildObject
-----ChildObject
....

I use this code:

Dim formatter As New
System.Xml.Serialization.XmlSerializer(_databaseSettings.GetType)
Dim settingsFile As New System.IO.FileStream("Settings.xml",
IO.FileMode.Create)
Try
formatter.Serialize(settingsFile, _databaseSettings)
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
settingsFile.Close()
End Try

<Serializable()> _
Public Class DataBaseSettings
Public Test As String
Public Items As Hashtable
End Class

When I try to run the code, I get an error when dimming the new formatter.
The error is: Additional information: There was an error reflecting type
'MyWinApp.Form1.DataBaseSettings'.

If I comment out "Public Items As Hashtable" serialization works just
fine, so the hashtable is the problem.

What am I doing wrong? Later I need to store objects in the hashtable. These
are also serializable individually. Do I need to do more than just add them
to the hashtable?

Thanks in advance

Klaus
 
M

Marc Scheuner [MVP ADSI]

This has been bugging me for days now...
I need to xmlserialize an object which contains a
collection/hashtable/array/whatever of childobjects.

That in itself shouldn't be a problem - I've done it ;-)
<Serializable()> _
Public Class DataBaseSettings
Public Test As String
Public Items As Hashtable
End Class

What I found to be a bit odd was the fact that each property of the
class I wanted to serialize had to have both a Get and a Set method -
if you have a "read-only" property, without a Set method, that
property won't be serialized.

Also, the class you're about to serialize has to have a standard
constructor without any parameters, otherwise the serialization
doesn't work.

I haven't tried Hashtable's yet - I know ArrayList's work without a
hitch.

So maybe you need to a) add a standard parameter-less constructor to
your class (both the parent class which contains the child objects, as
well as all the child classes, too), and b) try to use an ArrayList
instead of a Hashtable (just for testing now, to see if it works that
way).

Marc
 
G

Guest

Klaus, the below link may shed some light on the problem:

http://groups.google.com/groups?hl=...ionary&meta=group%3Dmicrosoft.public.dotnet.*

I have recently been looking into XmlSerializing my objects (which contain ArrayList of other objects). The IXmlSerializable interface is very useful for controlling how the XmlSerializer serializes/deserializes your objects. It contains 3 methods - ReadXml, WriteXml and GetSchema.

This interface is not currently intended for developer use, but this is apparently changing in the 2.0 version of the framework.

Hope this helps
Dan
 
K

Klaus Jensen

Marc Scheuner said:
That in itself shouldn't be a problem - I've done it ;-)

Knowing it IS in fact possible is a relieif. :)
So maybe you need to a) add a standard parameter-less constructor to
your class (both the parent class which contains the child objects, as
well as all the child classes, too), and b) try to use an ArrayList
instead of a Hashtable (just for testing now, to see if it works that
way).

I have now tried the stuff you suggested, but I keep getting the message
"There was an error generating the XML document."

I created two very simple classes to test it:

Public Class Order
Public Buyer As String
Public OrderDetails As New ArrayList
Public Sub New()
End Sub
End Class

Public Class OrderDetails
Private _item As String
Private _quantity As Integer
Public Sub New()
End Sub
Public Property Item() As String
Get
Return _item
End Get
Set(ByVal Value As String)
_item = Value
End Set
End Property
Public Property Quantity() As Integer
Get
Return _quantity
End Get
Set(ByVal Value As Integer)
_quantity = Value
End Set
End Property
End Class

Individually I can create both an order-object and an orderdetails-object,
and serialize them. Works perfectly!

I have also tried...:
order.OrderDetails.Add("Car")
order.OrderDetails.Add("Cow")

and then serializin the order object. Works perfectly!

But when I add an orderDetail-object to order.OrderDetails and try to
serialize the order-object, I get the error "There was an error generating
the XML document."

So... I can serialize an orderdetails-object, I can serialize an arraylist
with strings, but I can't serialize an arraylist of orderdetails-objects...
I am puzzled - and clueless on what to try next, I must admit.

- Klaus
 
K

Klaus Jensen

Klaus Jensen said:
So... I can serialize an orderdetails-object, I can serialize an arraylist
with strings, but I can't serialize an arraylist of orderdetails-objects...
I am puzzled - and clueless on what to try next, I must admit.

But then I did some more googling found this:
http://www.dotnet247.com/247reference/msgs/43/218167.aspx

The XmlElement-type needed to be defined for the arraylist - declare what
type of objects populated the arraylist:
<XmlElement(Type:=GetType(OrderDetails))> _

Added that - and voila!

And when that was added, the classes could be reduced to somethig as simple
as this:

Public Class Order
Public Buyer As String
<XmlElement(Type:=GetType(OrderDetails))> _
Public OrderDetails As New ArrayList
End Class
Public Class OrderDetails
Public Item As String
Public Quantity As Integer
End Class
It seems no blank constructors or properties are needed, since this code
works fine. :)
I used this code to test:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim order As New Order
order.Buyer = "Klaus"
Dim orderdetails As New OrderDetails
orderdetails.Item = "Beer"
orderdetails.Quantity = 1
order.OrderDetails.Add(orderdetails)
orderdetails = New OrderDetails
orderdetails.Item = "Peanuts"
orderdetails.Quantity = 1
order.OrderDetails.Add(orderdetails)
Dim formatter As New System.Xml.Serialization.XmlSerializer(order.GetType)
Dim settingsFile As New System.IO.FileStream("Order.xml",
IO.FileMode.Create)
Try
formatter.Serialize(settingsFile, order)
Catch ex As Exception
InputBox("", , (ex.Message))
Finally
settingsFile.Close()
End Try
End Sub

and the output in the order.xml-file was:

<?xml version="1.0" ?>
<Order xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Buyer>Klaus</Buyer>
<OrderDetails>
<Item>Beer</Item>
<Quantity>1</Quantity>
</OrderDetails>
<OrderDetails>
<Item>Peanuts</Item>
<Quantity>1</Quantity>
</OrderDetails>
</Order>

I am convinced de-serializing the order-object is trivial, but I have no
more time today to test it.

Thanks for your help, guys! :)

- Klaus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top