Error Deserializing NameObjectCollection Object Using SoapFormatter

P

Phillip Galey

I have an object called Place which contains only string properties and has
the <Serializable()> flag before the class name declaration. I also have a
collection object called Places, which is implemented using Inherits
System.Collections.Specialized.NameObjectCollectionBase and also has the
<Serializable()> flag before the class name declaration.

In the calling code, I'm successfully serializing the object to an XML file
using a SoapFormatter object and a FileStream object. However, I am running
into a problem in deserializing the data back into the Places object. The
deserialize method returns the error: "The constructor to deserialize an
object of type TestingPad.Places was not found." Any ideas what might cause
the Deserialize method to return this error while the Serialize method works
flawlessly? Below is the code I'm using:
<Serializable()> Public Class Place
Private strCity As String
Private strState As String
Public Sub New()
strCity = ""
strState = ""
End Sub
Public Sub New(ByVal City As String, ByVal State As String)
strCity = City
strState = State
End Sub
Public Property City() As String
Get
Return strCity
End Get
Set(ByVal Value As String)
strCity = Value
End Set
End Property
Public Property State() As String
Get
Return strState
End Get
Set(ByVal Value As String)
strState = Value
End Set
End Property
End Class

<Serializable()> Public Class Places
Inherits System.Collections.Specialized.NameObjectCollectionBase
Public Sub New()
MyBase.New()
End Sub
Public Sub Add(ByVal Key As String, ByVal objPlace As Place)
MyBase.BaseAdd(Key, objPlace)
End Sub
Public Sub Remove(ByVal Key As String)
MyBase.BaseRemove(Key)
End Sub
Default Public ReadOnly Property Item(ByVal Key As Object) As Place
Get
If IsNumeric(Key) Then
Return MyBase.BaseGet(CType(Key, Integer))
Else
Return MyBase.BaseGet(CType(Key, String))
End If
End Get
End Property
End Class

Imports System.Runtime.Serialization.Formatters.Soap
Private Sub cmdTestSerialization_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles Button4.Click
Dim objPlaces As New Places()
Dim fs As System.IO.FileStream
Dim sf As SoapFormatter = New SoapFormatter()
objPlaces.Add("A", New Place("Moreno Valley", "CA"))
objPlaces.Add("B", New Place("Boston", "MA"))
objPlaces.Add("C", New Place("Moscow", "GA"))
fs = IO.File.Open("c:\myfile.xml", IO.FileMode.OpenOrCreate,
IO.FileAccess.ReadWrite)
Try
sf.Serialize(fs, objPlaces)
Catch x As System.Runtime.Serialization.SerializationException
MessageBox.Show("Failed to serialize. Reason: " & x.Message)
Finally
fs.Close()
End Try
fs = Nothing
sf = Nothing
objPlaces = Nothing
fs = IO.File.Open("c:\myfile.xml", IO.FileMode.Open, IO.FileAccess.Read)
sf = New SoapFormatter()
Try
objPlaces = CType(sf.Deserialize(fs), Places) '<=======
ERROR LINE
Catch x As System.Runtime.Serialization.SerializationException
MessageBox.Show("Failed to deserialize. Reason: " & x.Message)
Catch y As Exception
MessageBox.Show("Error occured: " & y.Message)
Finally
fs.Close()
End Try
fs = Nothing
sf = Nothing
objPlaces = Nothing
End Sub
 
C

Codemonkey

Add the following constructor to your class (watch out for stupid line
breaks in the post:

--------------------------------

Protected Sub New(ByVal info As
System.Runtime.Serialization.SerializationInfo, ByVal context As
System.Runtime.Serialization.StreamingContext)

MyBase.New(info, context)

End Sub
------------------------------
This constructor is required by anthing that contains a hashtable like
object for its base as it contains special code to deserialize itself
instead of letting the framework do it. Anywhere you inherit from a class
that has a constructor like it, make sure you include this constructor in
your derived class.

Hope this helps,

Trev.
 
P

Phillip Galey

Wonderful. Thanks. That worked.

Codemonkey said:
Add the following constructor to your class (watch out for stupid line
breaks in the post:

--------------------------------

Protected Sub New(ByVal info As
System.Runtime.Serialization.SerializationInfo, ByVal context As
System.Runtime.Serialization.StreamingContext)

MyBase.New(info, context)

End Sub
------------------------------
This constructor is required by anthing that contains a hashtable like
object for its base as it contains special code to deserialize itself
instead of letting the framework do it. Anywhere you inherit from a class
that has a constructor like it, make sure you include this constructor in
your derived class.

Hope this helps,

Trev.


have
 

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