Serialization / Deserialization of Objects With Version Changes#

CSLA as well as well as the proxy architecture I created for my last project, utilize serialization of objects to be passed across the wire, and deserialized on the other side into the same type of object.

This is different from passing datasets, which are then read into business objects.  We are actually passing the serialized version of the business object.

So what happens if you make a change to a business object such as adding a public property.  Will clients who have the old version of the Business Object be forced to upgrade? 

To see the answers along with some sample code for testing this out click on the link to read the full article.

So lets say you have a class that exposes 20 properties and 40 methods.  This business object is deployed on hundreds of clients computers.  When they send the BizObject over the wire, it is deserialized back into the exact same object on the server. 

But now, for whatever reason, you need to add 1 property to this BizObject.  For the current set of clients using this business object, you don't really need to deploy the updated change unless you have to in order to keep it from breaking.

So do you need to redeploy?  Probably not.

I serialzied a business object into a base64 encoded string and then added a public property to the object and tried to deserialize it with the "old" serialized string.  The result?  It worked.  The properties that had values when I first serialized it kept their values.  The fact that there were new properties didn't cause a problem.

How about going the other way: removing a public property that had a value when it was serialized, but doesn't exist with deserialized.  Again, this works. 

When doesn't it work?  When you are trying to deserialze into a different class, or a different namespace for the same class. 

So you can't serialize classA and deserialize it into classB, even if both expose the exact same signature.  The same goes for namespaces.  If you serialize classA, and then change it's namespace and try to deserialize it, you will get an exception.

You can try it out with the following code:

Imports WindowsApplication1.ASDF


Public Class Form1

Private Sub toString_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdToString.Click
Dim o As New A
o.A11 = "this is a test"
o.Asdf1 = "another test"

Me.TextBox2.Text = EncodeBase64(o.CloneString)
MsgBox(EncodeBase64(o.CloneString))
End Sub

Private Sub fromString_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fromString.Click
Dim o As A = A.Hydrate(DecodeBase64(Me.TextBox1.Text))
MsgBox(o.A11)
MsgBox(o.Asdf1)
MsgBox(o.asdfdsa)
End Sub

Public Function EncodeBase64(ByVal input As String) As String
Dim strBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(input)
Return System.Convert.ToBase64String(strBytes)
End Function

Public Function DecodeBase64(ByVal input As String) As String
Return System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(input))
End Function

End Class


<Serializable()> _
Public Class Parent

Public Function CloneString() As String
Dim bFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim stream As New System.IO.MemoryStream()
bFormatter.Serialize(stream, Me)
stream.Flush()
stream.Position = 0
Dim bytes() As Byte = stream.ToArray()

Return System.Text.Encoding.Default.GetString(bytes)
End Function

Public Shared Function StringToStream(ByVal str As String) As System.IO.Stream
Return New System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(str))
End Function

End Class

<Serializable()> _
Public Class A
Inherits Parent

Private a1 As String
Private asdf As String
Public Property A11() As String
Get
Return a1
End Get
Set(ByVal value As String)
a1 = value
End Set
End Property

Public Property Asdf1() As String
Get
Return asdf
End Get
Set(ByVal value As String)
asdf = value
End Set
End Property
Public Function asdfdsa() As String
Return "Asdf"
End Function
Public Shared Function Hydrate(ByVal s As String) As A
Dim bFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim stream2 As System.IO.MemoryStream = StringToStream(s)
stream2.Flush()
stream2.Position = 0
Dim newClone As A
newClone = CType(bFormatter.Deserialize(stream2), A)
Return newClone
End Function

End Class


 

Categories:  |  |  | 
Sunday, April 23, 2006 6:35:24 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Name
E-mail
(will show your gravatar icon)
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

All content © 2008, Christopher May, Inc
Open Job Positions
On this page
Google Ads
This site
Calendar
<April 2006>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
Archives
Sitemap
Blogroll OPML
Disclaimer

Powered by: newtelligence dasBlog 1.9.6264.0

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Send mail to the author(s) E-mail

Theme design by Jelle Druyts


Pick a theme: