Introduction
By default, Generic Collections can not be serialized using an XML serializer. I am trying to create a generic collection that can be serialized in XML format.
Public Class CollectionBase(Of T)
Inherits System.Collections.ObjectModel.Collection(Of T)
Implements System.Xml.Serialization.IXmlSerializable
About this Collection
When we implement an XmlSerializable
object, we must inherit it from IXmlSerializable
. And then, we must implement three methods: GetSchema
, ReadXml
, WriteXml
. In GetSchema
, we must return a string that contains the XML schema about the object (we leave it blank in this version!). The ReadXml
method will contain statements that deserialize the XML to objects, and finally in WriteXml
, we serialize our collection into XML.
Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) _
Implements System.Xml.Serialization.IXmlSerializable.ReadXml
Dim pc() As PropertyInfo = GetType(T).GetProperties()
While reader.Read()
If reader.Name = GetType(T).Name Then
reader.Read()
If pc.Length > 0 Then
Dim ti As T = GetInstance()
For i As Int32 = 0 To pc.Length - 1
If pc(i).CanRead And pc(i).CanWrite Then
Dim st As SerilalizeType = GetSerilalizeType(pc(i).PropertyType)
If st = SerilalizeType.Complex Then
Dim o As Object = GetInstance(pc(i).PropertyType)
DesrializeObject(reader, o, pc(i).Name)
pc(i).SetValue(ti, _
Convert.ChangeType(o, pc(i).PropertyType), _
Nothing)
ElseIf st = SerilalizeType.Guid Then
Dim strGuid As String = reader.ReadElementString(pc(i).Name)
Dim newId As Guid = New Guid(strGuid)
pc(i).SetValue(ti, New Guid(strGuid), Nothing)
ElseIf st = SerilalizeType.Array Then
Dim o As Object = Nothing
DesrializeArray(reader, o, pc(i).PropertyType)
pc(i).SetValue(ti, _
Convert.ChangeType(o, pc(i).PropertyType), _
Nothing)
ElseIf st = SerilalizeType.ICollection Then
Dim o As Object = Nothing
DesrializeCollection(reader, o, pc(i).PropertyType)
pc(i).SetValue(ti, _
Convert.ChangeType(o, pc(i).PropertyType), _
Nothing)
Else
pc(i).SetValue(ti, _
Convert.ChangeType( _
reader.ReadElementString(pc(i).Name), pc(i).PropertyType), _
Nothing)
End If
End If
Next
Me.Add(ti)
End If
End If
End While
End Sub
Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) _
Implements System.Xml.Serialization.IXmlSerializable.WriteXml
Dim pc() As PropertyInfo = GetType(T).GetProperties()
Dim ti As T = Nothing
For i As Int32 = 0 To Me.Items.Count - 1
ti = Me.Item(i)
writer.WriteStartElement(GetType(T).Name)
For j As Int32 = 0 To pc.Length - 1
If pc(j).CanRead And pc(j).CanWrite Then
writer.WriteStartElement(pc(j).Name)
Dim st As SerilalizeType = GetSerilalizeType(pc(j).PropertyType)
If st = SerilalizeType.Complex Or _
st = SerilalizeType.Array Or _
st = SerilalizeType.ICollection Then
writer.WriteRaw(SerializeObject(pc(j).GetValue(ti, Nothing)))
Else
writer.WriteString(pc(j).GetValue(ti, Nothing).ToString())
End If
writer.WriteEndElement()
End If
Next
writer.WriteEndElement()
Next
End Sub
Using the Code
As is usual, here is how we use Generic Collections:
Dim MyCol As New DNE.Components.CollectionBase(Of SomeObject)
I suggest inheriting your collection from this class. Our collection can now deserialize simple properties like string, integer, and arrays and objects that inherits from ICollection
.
ToDo
Support serialization for Hashtables, Enums, and ....
History
- Version 0.2: Support for
Array
and ICollection
, fixed some bugs. 28/11/2007. - Version 0.1: Initial release. 11/11/2007.