序列化自定义对象生成带有错过信息的文件

时间:2013-12-02 12:47:31

标签: .net vb.net serialization

我有问题。当我尝试serialize我的自定义对象列表时,我的所有信息都会丢失。

我的序列化输出:

  <?xml version="1.0" ?> 
- <ArrayOfCustomObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <CustomObject /> 
  <CustomObject /> 
  <CustomObject /> 
  </ArrayOfCustomObject>

我有一些代码演示了我的序列化方法:

Dim xmlSerializer As New XmlSerializer(GetType(List(Of CustomObject )))

Using fileStrm As New StreamWriter("C:\Users\MyUser\Desktop\xmlTest.xml", FileMode.OpenOrCreate)
   xmlSerializer.Serialize(fileStrm, objectsList)
End Using

CustomObject是:

Imports System.Xml.Serialization

<XmlRootAttribute("SomeObject")>
Public Class CustomObject 

    Sub New()

    End Sub

    Sub New(ByVal someTable As DataTable, ByVal id As Integer, ByVal title As String)
        _someTable = someTable 
        _title = title
        _id = id
    End Sub

    Private _someTable As DataTable
    Private _title As String
    Private _id As Integer

    <XmlAttribute("Title")>
    Public ReadOnly Property Title As String
        Get
            Return _title
        End Get
    End Property

    <XmlAttribute("Table")>
    Public ReadOnly Property SomeTable As DataTable
        Get
            Return _someTable 
        End Get
    End Property

    <XmlAttribute("ID")>
    Public ReadOnly Property ID As Integer
        Get
            Return _id
        End Get
    End Property
End Class

哪里可以成为我的错误? (如果c#更适合随意回答)

1 个答案:

答案 0 :(得分:3)

XmlSerializer将忽略没有setter的属性。

在您的情况下,例如,此属性将被忽略:

<XmlAttribute("Table")>
Public ReadOnly Property SomeTable As DataTable
    Get
        Return _someTable 
    End Get
End Property

因为它是只读的:序列化器被设计为在两个方向上工作,然后它是无意义的(从它的角度来看)序列化它以后无法反序列化的东西。

它会忽略一个属性有很多原因(详见MSDN,列表很长,并不总是那么明显)。如果你想保留XmlSerializer,那么可能做的是添加一个setter方法或创建一个特殊对象(代理,类似于BinarySerializer所做的)以进行反序列化转发到当前对象的属性:

<XmlRootAttribute("SomeObject")>
Public Class CustomObjectSurrogate

    Sub New()
        ' Uncomment this if you plan to support deserialization too
        ' _realObject = New CustomObject()
    End Sub

    Sub New(realObject As CustomObject)
        _realObject = realObject
    End Sub

    Private _realObject As CustomObject

    <XmlAttribute("Table")>
    Public Property SomeTable As DataTable
        Get
            Return _realObject.SomeTable 
        End Get
        Set(value As DataTable)
            ' Ignore, this is a dummy object for serialization
        End Set
    End Property

    ' More properties here
End Class

有了这个,你将序列化CustomObjectSurrogagte(只不过是一个瘦的包装来访问CustomObject属性)。通过这种方式,您可以保持CustomObject实现尽可能干净。

嗯,当然你总是可以实现IXmlSerializable界面来强制XmlSerializer完全按照自己的意愿行事,但这可能需要做很多工作(特别是如果序列化界面可能/会有很大不同当前对象模型)。

我喜欢 surragte 解决方案,特别是因为(没有IXmlSerializable的所有肮脏的工作)允许我序列化(并最终反序列化)不同的东西(我想,例如,关于字典,通用集合和日期)。在CustomObjectSurrogate中设置CustomObject嵌套类,您甚至不需要为CustomObject属性设置公共设置器。