【问题标题】:Serialize custom object produce file with missed info序列化缺少信息的自定义对象生成文件
【发布时间】:2013-12-18 04:30:38
【问题描述】:

我有问题。当我尝试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#更合适,可以随意回答)

【问题讨论】:

  • 您忘记为流写入器 C:\Users\MyUser\Desktop\xmlTest 提供扩展名
  • @Terror.Blade tnxs 发表评论,但这不是我的问题的原因。我手动编辑了这段代码,只是错过了扩展。

标签: .net vb.net serialization


【解决方案1】:

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 属性提供公共设置器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多