Hello,
I'm writing a TypeConverter for a class which inherits arraylist, but
deserializing it always results in an arraylist, which causes an
InvalidCastExce ption. If anyone can point out what I'm doing wrong here,
I'd really appreciate it.
The class:
<TypeConverter( GetType(CXMLObj ectListConverte r))> _
Public Class CXMLObjectList
Inherits ArrayList
#Region "Constants"
Private Const XML_ATTRIBUTE_C ount As String = "Count"
Private Const XML_ATTRIBUTE_C lassName As String = "ClassName"
#End Region
#Region "New()"
Public Sub New()
MyBase.New()
End Sub
#End Region
#Region "New(ByVal RootElement As String)"
Public Sub New(ByVal RootElement As String)
MyBase.New()
mRootElement = RootElement
End Sub
#End Region
#Region "New(ByVal RootElement As String, ByVal TotalCount As Integer)"
Public Sub New(ByVal RootElement As String, ByVal TotalCount As
Integer)
MyBase.New()
mRootElement = RootElement
mTotalCount = TotalCount
End Sub
#End Region
#Region "New(ByVal xDoc As XmlDocument)"
Public Sub New(ByVal xDoc As XmlDocument)
Me.New(xDoc.Chi ldNodes(0))
RootElement = xDoc.ChildNodes (0).Value
End Sub
#End Region
#Region "New(ByVal xNode As XmlNode)"
Public Sub New(ByVal xNode As XmlNode)
Dim childValue As String
TotalCount = CInt(xNode.Attr ibutes(XML_ATTR IBUTE_Count).Va lue)
For Each childNode As XmlNode In xNode.ChildNode s
If xNode.Item(chil dNode.Name).Has ChildNodes Then
Dim myType As Type =
Type.GetType(ch ildNode.Attribu tes(XML_ATTRIBU TE_ClassName).V alue)
Dim types(0) As Type
types(0) = GetType(XmlNode )
' Get the public instance constructor for the loaded type
Dim constructorInfo Obj As ConstructorInfo = _
myType.GetConst ructor(BindingF lags.Instance
Or _
BindingFlags.Pu blic, Nothing, _
CallingConventi ons.HasThis, types, Nothing)
If Not (constructorInf oObj Is Nothing) Then
Dim parms(0) As Object
parms(0) = CType(childNode , XmlNode)
Me.Add(construc torInfoObj.Invo ke(parms))
End If
End If
Next
End Sub
#End Region
#Region "Members"
Private mRootElement As String
Private mTotalCount As Integer
#End Region
#Region "Properties "
Public Property TotalCount() As Integer
Get
If mTotalCount = 0 Then
mTotalCount = Me.Count
End If
Return mTotalCount
End Get
Set(ByVal Value As Integer)
mTotalCount = Value
End Set
End Property
Public Property RootElement() As String
Get
Return mRootElement
End Get
Set(ByVal Value As String)
mRootElement = Value
End Set
End Property
#End Region
#Region "toXMLDocum ent"
Public Function toXMLDocument() As XmlDocument
Return toXMLDocument(N othing)
End Function
Private Function toXMLDocument(B yVal objectList As ArrayList) As
XmlDocument
Dim xmlStream As New MemoryStream
Dim xml As New XmlTextWriter(x mlStream, Encoding.UTF8)
xml.WriteStartD ocument()
xml.WriteStartE lement(RootElem ent)
xml.WriteAttrib uteString(XML_A TTRIBUTE_Count, TotalCount.ToSt ring)
If IsNothing(objec tList) Then
objectList = Me
End If
For Each xObject As CXMLObject In objectList
xObject.toXML(x ml)
Next
xml.WriteEndEle ment()
xml.WriteEndDoc ument()
xml.Flush()
xmlStream.Seek( 0, SeekOrigin.Begi n)
Dim xmldoc As New XmlDocument
xmldoc.Load(xml Stream)
Return xmldoc
End Function
#End Region
End Class
The TypeConverter:
Public Class CXMLObjectListC onverter
Inherits TypeConverter
Public Overloads Overrides Function CanConvertFrom( ByVal context As
System.Componen tModel.ITypeDes criptorContext, ByVal sourceType As
System.Type) As Boolean
If sourceType Is GetType(XmlDocu ment) OrElse sourceType Is
GetType(XmlNode ) Then
Return True
End If
If sourceType Is GetType(String) Then
Return True
End If
Return MyBase.CanConve rtFrom(context, sourceType)
End Function
Public Overloads Overrides Function ConvertFrom(ByV al context As
System.Componen tModel.ITypeDes criptorContext, ByVal culture As
System.Globaliz ation.CultureIn fo, ByVal value As Object) As Object
If TypeOf value Is XmlDocument OrElse value Is GetType(XmlNode )
Then
Return New CXMLObjectList( CType(value, XmlNode))
End If
If TypeOf value Is String Then
Dim xDoc As New XmlDocument
xDoc.LoadXml(CS tr(value))
Return New CXMLObjectList( xDoc)
End If
Return MyBase.ConvertF rom(context, culture, value)
End Function
Public Overloads Overrides Function CanConvertTo(By Val context As
System.Componen tModel.ITypeDes criptorContext, ByVal destinationType As
System.Type) As Boolean
If destinationType Is GetType(XmlDocu ment) OrElse
destinationType Is GetType(XmlNode ) Then
Return True
End If
If destinationType Is GetType(String) Then
Return True
End If
Return MyBase.CanConve rtTo(context, destinationType )
End Function
Public Overloads Overrides Function ConvertTo(ByVal context As
System.Componen tModel.ITypeDes criptorContext, ByVal culture As
System.Globaliz ation.CultureIn fo, ByVal value As Object, ByVal
destinationType As System.Type) As Object
If destinationType Is GetType(XmlDocu ment) OrElse
destinationType Is GetType(XmlNode ) Then
Return CType(value, CXMLObjectList) .toXMLDocument
End If
If destinationType Is GetType(String) Then
Return CType(value, CXMLObjectList) .toXMLDocument. ToString
End If
Return MyBase.ConvertT o(context, culture, value, destinationType )
End Function
End Class
The Code I'm using to test:
Dim list As New CXMLObjectList
Dim los As New LosFormatter
Dim sw As New StringWriter
los.Serialize(s w, list)
list = Nothing
list = los.Deserialize (sw.GetStringBu ilder.ToString)
Thanks in advance,
-Eric