XML Serializing a simple Structure

  • Thread starter Thread starter Farouche
  • Start date Start date
F

Farouche

Hi all

I have made two simple methods to serialize/deserialize a simple data
structure to my database using SoapFormatting.

This actually works just great, when the structures stays the same. BUT if I
change the structure, say adds a field, I get an error when trying to
deserialize the allready serialized object from the database saying that the
number of fields of the structure does not match the number of fields in the
one I'm trying to deserialize.


Thids is quite a problem since I'm not able to make any future changes to my
data.


Does anyone know how to get about this problem ??


Thanks in Advance
Farouche

Public Shared Function StreamToString(ByVal st As System.IO.Stream) As
String
st.Position = 0
If st.CanRead And st.CanSeek Then
Dim by(Convert.ToInt32(st.Length - 1)) As Byte
st.Read(by, 0, by.Length)
st.Position = 0
Return System.Text.Encoding.UTF8.GetString(by)
End If
End Function

Public Shared Function StringToStream(ByVal s As String) As System.IO.Stream
Dim by(s.Length - 1) As Byte
by = System.Text.Encoding.UTF8.GetBytes(s)
Dim st As System.IO.Stream = New System.IO.MemoryStream(s.Length)
st.Write(by, 0, by.Length)
st.Position = 0
Return st
End Function



Public Shared Function ObjToXml(ByVal obj As Object) As String
Dim Stream As System.IO.Stream = New System.IO.MemoryStream()
Dim SoapFormatter As System.Runtime.Serialization.IFormatter = New
System.Runtime.Serialization.Formatters.Soap.SoapFormatter()
Dim SoapString As String

SoapFormatter.Serialize(Stream, obj)

SoapString = StreamToString(Stream)
Stream.Close()
Stream = Nothing

Return SoapString
End Function

Public Shared Function XmlToObj(ByVal Xml As String) As Object
Dim SoapFormatter As System.Runtime.Serialization.IFormatter = New
System.Runtime.Serialization.Formatters.Soap.SoapFormatter()
Dim Stream As System.IO.Stream = StringToStream(Xml)
Dim obj As Object

obj = SoapFormatter.Deserialize(Stream)
Stream.Close()
Stream = Nothing
Return obj
End Function´
 
Hi Farouche,

This is an age old problem rearing its head in the arena of XML - What do
I do when I have existing data and I've changed the data format?

The simple answer is that you have to convert it. You'll need to know when
you are receiving an old format object and call a converter that inserts the
added fields and removes any deleted field, converts any values that have
changed type, etc, etc.

One way to do this is to place your XML into a System.Xml.XmlDataDocument
and manipulate it using that. You can do the transformation using code or
using XSLT if you know it. Then take the XML out again and pass it to the
deserialiser.

Another way is to have two deserialisers - one that works for the old kind
of object and one for the new. [Q. Why does your code accept Object - why not
the actual type?]. Every time that you change your format you'll have to add
another deserialiser to your collection. The 'old' deserialiser would populate
an 'old' object which you would then transfer to an instance of a 'new'
object.

If you have no way of telling whether you have an old or new format
serialised object, then you must use the new serialiser, wait for the
Exception, catch it and then call the old serialiser. If you have several
versions then you must cascade them. Ughh!

To guard against having to jump through all these hoops, it is a good idea
to start versioning them so that you can detect which deserialiser you'll
need.

Another possibility is to add in all the fields that you can anticipate at
this time. This will cut down the amount of versioning but there are bound to
be unanticipated fields.

Another possibility, still nothing elegant, is to have an 'overflow'
object in which you add new fields. This could be simply an 'oMoreFields As
Object' field. You could utilise inheritance so that succesive versions are
still contained within the same clas hierarchy.

Another possibility, and one that leaves your program unblemished, is to
write a utility program which does the conversion for you. It would have to be
rewritten (well, edited) for each version change. It would take all the
existing serialised data and apply the required adds/changes/deletes.

Choices, choices. Decisions, decisions :-(

And there will be more from others too, I expect. :-)

Regards,
Fergus
 
Back
Top