Can I deserialize an object when the underlying class has been changed slightly?
Asked Answered
V

4

7

I've written a custom class MyClass and marked it with the <Serializable()> attribute. I have a set of binary files on my hard drive that I've serialized using BinaryFormatter that came from instances of MyClass.

I've recently changed the structure of MyClass slightly (added some properties, deleted some properties, changed a few methods, etc).

What happens when I try to deserialize the existing objects to this changed class using the code below? I've tried it and not had an error thrown or anything - but surely it can't deserialize properly when the class has changed? Is there a way I can get some useful information out of the serialized files even though I've updated the class?

Thanks.


Here's the code I'm using to do the serialization:

Public Sub serializeObject(ByVal obj As Object, ByVal outFilename As String)
    Dim fStream As FileStream
    Try
        fStream = New FileStream(outFilename, FileMode.Create)
        Dim bfmtr As New BinaryFormatter
        bfmtr.Serialize(fStream, obj)
        fStream.Close()
    Catch ex As Exception
        MsgBox("Failed to serialize: " & ex.Message)
        Throw
    End Try
End Sub

And to do the deserialization I'm using:

myObj = CType(deserializeObject("C:\myobject.bin"), MyClass))

Where deserializeObject is:

Public Function deserializeObject(ByVal srcFilename As String) As Object
    If File.Exists(srcFilename) Then
        Dim fStream As Stream = File.OpenRead(srcFilename)
        Dim deserializer As New BinaryFormatter
        Dim returnObject As Object = deserializer.Deserialize(fStream)
        fStream.Close()
        Return returnObject
    Else
        Throw New ApplicationException("File not found: " & srcFilename)
    End If
End Function
Vanhorn answered 10/5, 2011 at 11:41 Comment(0)
G
1

In the past I have had compatability issues between minor changes in serialized objects using the binaryformatter, and I also do not fully understand why. There is a "UnsafeDeserialize" method which sort of implies a more compatible "deserialize".

The "What Happens" is when it does have a compatibility breaking change, you simply cannot recreate the object. I don't know if there is any way to recreate it again short of using old code structure.

I have used XML serialization in these cases which seems to be much safer (and is readable so you could potentially correct any issue you have later)

The cost is that the size of the XML serialized objects is considerably larger in most cases. Compressing/decompressing can help that.

Here are my XML routines I use for this.

''' <summary>
''' Serializes as object into XML format
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The type of the object being serialized</typeparam>
''' <param name="oObj">The object to serialize</param>
''' <returns>The XML Document (string) that is the serialized object in text form</returns>
Public Shared Function XmlSerialize(Of ObjectType)(ByVal oObj As Object) As String
    Dim sb As New System.Text.StringBuilder
    Dim sw As New IO.StringWriter(sb)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    x.Serialize(sw, oObj)
    Return sb.ToString
End Function
''' <summary>
''' DeSerializes and object from an XML Document
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The Object type that will be returned (That the XML Data is derived from)</typeparam>
''' <param name="oObj">The Object (in it's XML Document serialized format)</param>
''' <returns>The new object</returns>
Public Shared Function XmlDeSerialize(Of ObjectType)(ByVal oObj As String) As ObjectType
    Dim sr As New IO.StringReader(oObj)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    Dim out As ObjectType = CType(x.Deserialize(sr), ObjectType)
    Return out
End Function
Gosplan answered 25/6, 2011 at 16:51 Comment(1)
Something else to mention. XML may not be suitable for your purpose because I don't know how it deals with "Private" data in the serailization. Needless to say it's a different process then Binary Serialization.Gosplan
E
1

You will need to control the serialization and deserialization process. You may use the ISerializable interface to do this.

Take a look at:

http://msdn.microsoft.com/en-us/library/ty01x675.aspx, there is some useful information in the section "Implementing the ISerializable Interface".

Expulsive answered 26/7, 2011 at 17:15 Comment(0)
M
0

Adding and removing fields SHOULD NOT be of any problem - I have empirical proof of that, not that I know how the serialization works in the detail.

You could have problems when changing the name of the private properties. All other things, even reordering the fields, you're cool.

Meit answered 10/5, 2011 at 13:38 Comment(4)
If you remove fields, you will get an error if the property exists in the serialized data. Adding fields should be fine. You also can't change the assembly version # or strong naming key as these will also cause deserialization to fail.Hedvah
@Robert. You are completely wrong about this. If every property was required to exist in the serialized format then we wouldn't have Data Contract Attributes like [IgnoreDataMember].Nylons
This is binary serialization. You are correct when you are referring to XML serialization, but binary serialiation will fail on deserialization if you remove a property from an object after serialization.Hedvah
@Robert - from the experience, didn't ever had this problem.Alien
N
0

I haven't looked at the actual implementation of BinaryFormatter.Deserialize() so I will speculate.

I dont think that it is the responsibility of the deserializer to ensure that all the properties of a class are not null. There are plenty of scenarios where null properties are totally valid and cause no problems.

Now I can answer your question:

I believe that adding properties to a class will not cause problems however, I do think that removing properties that you are attempting to deserialize will cause errors.

Nylons answered 29/7, 2011 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.