【问题标题】:Serialize an object that contains a list of objects序列化包含对象列表的对象
【发布时间】:2014-08-08 13:34:37
【问题描述】:

我已经构建了一个 NotInheritable Serilizer,它可以成功地对我的所有类和类列表进行序列化。 直到我建立了一个包含类列表的类列表。 我得到运行时异常:生成 XML 文档时出错。导致一个完全空的 XML :(

这些是我要序列化的类:

<System.Serializable> _
<System.Xml.Serialization.XmlInclude(GetType(StatisticItem))> _
Public Class Statistic
    Public StatItem As New list(Of StatisticItem)
    'Bla bla bla
end class


<Serializable> _
Public Class StatisticItem              
        Private stStatPath As String = ""    
        Private eStatType As StatType = 0
        Private iBatchNumber As Int32 = 0
end class

还有序列化器:

Public NotInheritable Class XmlSerializer       

    Public Shared Sub Serialize(Of T)(ByVal obj As T, sConfigFilePath As String)        
        Dim XmlBuddy As New System.Xml.Serialization.XmlSerializer(GetType(T))
        Dim MySettings As New System.Xml.XmlWriterSettings()
        MySettings.Indent = True
        MySettings.CloseOutput = True       
        Dim MyWriter As System.Xml.XmlWriter=System.Xml.XmlWriter.Create(sConfigFilePath,MySettings)        
        XmlBuddy.Serialize(MyWriter,obj) 
        MyWriter.Flush()
        MyWriter.Close()    

        ' ----- OLD CODE FOR SERIALIZE, NEXTLINE IN XML DOESNT WORK ON WIN CE -------, 
        ' B.T.W. Using This code to serilize gives the exact same fault             
        'Dim XmlBuddy As New System.Xml.Serialization.XmlSerializer(GetType(T))
        'Dim objStreamWriter As New StreamWriter(sConfigFilePath)
        'XmlBuddy.Serialize(objStreamWriter, obj)
        'objStreamWriter.Close()
    End Sub
 end class

这就是电话:

 XmlSerializer.Serialize(Of list(Of Statistic))(StatCollection, CommCtrl.PathStatisticFile)

如果我在 StatisticItem 中评论列表,一切正常。

我想如果我在 StatisticItem 中实现 IXmlSerializable 我可以告诉序列化程序如何工作以使其工作,但我在互联网上看到其他代码示例无需所有这些努力就可以工作 而且我更喜欢一个干净的解决方案,这与我所有其他课程大致相同。

希望你们能帮帮我

【问题讨论】:

  • Rob,这不会使您的代码不干净。添加你需要的东西并不是不必要的。你能添加它,测试它,并让我们知道它是否有效。修复没有损坏的东西是没有意义的。
  • 我只是在研究它,但现在我注意到我必须编写代码来编写统计和统计项的所有名称和值。当然还有之后阅读所有内容的代码。我知道必须有一种更简单的方法来序列化它。我制作了这样的序列化程序,因此它可以识别它接收到的对象类型。该死的你深夜烧烤
  • 序列化程序只会序列化Public 属性(使用您的代码)。不能把Privates 改成Publics 吗??
  • 我试过了,我没有在代码中包含公共属性。我仍在尝试一些事情,现在我有一个全新的外观,如果我今天早上无法修复,我将不得不使用 IXmlSerializable 包含手动输入所有内容。如果有人有好的提示,那就太糟糕了,任何帮助都是有用。

标签: vb.net serialization xmlserializer


【解决方案1】:

是的,解决了!老实说,我改变了很多小东西,以至于我仍然不知道原因是什么。 也许还有一些私人成员。 无论如何,也许代码对任何人都有用:

Public Class Statistic 

    'Properties         
    Private eStatName As String                     
    Private eStatSort As StatSort            
    Private StatItem As New list(Of StatisticItem)


    Public Property Name() As String
      Get
          Return eStatName
      End Get
      Set(ByVal value As String)
          eStatName = value
      End Set
    End Property

    'Other public properties
End class



Public Class StatisticItem  
    Private stStatPath As String = ""    
    Private eStatType As StatType = 0
    Private iBatchNumber As Int32 = 0

Public Property Path() As String
    Get
        Return stStatPath
    End Get
    Set(ByVal Value As String)
        stStatPath = Value
    End Set
End Property

' The other Public Properties

序列化器:

Public NotInheritable Class XmlSerializer

    ''' <summary>
    ''' Convert a class state into XML
    ''' </summary>
    ''' <typeparam name="T">The type of object</typeparam>
    ''' <param name="obj">The object to serilize</param>
    ''' <param name="sConfigFilePath">The path to the XML</param>
    Public Shared Sub Serialize(Of T)(ByVal obj As T, sConfigFilePath As String)        
        Dim XmlBuddy As New System.Xml.Serialization.XmlSerializer(GetType(T))
        Dim MySettings As New System.Xml.XmlWriterSettings()
        MySettings.Indent = True
        MySettings.CloseOutput = True       
        Dim MyWriter As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(sConfigFilePath,MySettings)      
        XmlBuddy.Serialize(MyWriter,obj) 
        MyWriter.Flush()
        MyWriter.Close()    
    End Sub



''' <summary>
''' Restore a class state from XML
''' </summary>
''' <typeparam name="T">The type of object</typeparam>
''' <param name="xml">the path to the XML</param>
''' <returns>The object to return</returns>
Public Shared Function Deserialize(Of T)(ByVal xml As String) As T      
    Dim XmlBuddy As New System.Xml.Serialization.XmlSerializer(GetType(T))
    Dim fs As New FileStream(xml, FileMode.Open)
    Dim reader As New Xml.XmlTextReader(fs) 
    If XmlBuddy.CanDeserialize(reader) Then
        Dim tempObject As Object = DirectCast(XmlBuddy.Deserialize(reader), T)         
        reader.Close()
        Return tempObject
    Else
        Return Nothing
    End If
End Function
end class

序列化器的调用:

Try                     
     XmlSerializer.Serialize(Of list(Of Statistic))(StatCollection, CommCtrl.PathStatisticFile)
Catch ex As Exception
     msgbox(ex.Message)
End Try

反序列化器的调用:

Try
     StatCollection = XmlSerializer.Deserialize(Of list(Of Statistic)(CommCtrl.PathStatisticFile)
Catch ex As Exception
     msgbox(ex.Message)
end Try

【讨论】:

    【解决方案2】:

    我也需要这样做,但要创建一个字符串。这是我的解决方案:

        Public Shared Function Serialize(Of T)(ByVal obj As T) As String
            Dim xml As New System.Xml.Serialization.XmlSerializer(GetType(T))
            Dim ns As New System.Xml.Serialization.XmlSerializerNamespaces()
            ns.Add("", "") 'No namespaces needed.
            Dim sw As New IO.StringWriter()
            xml.Serialize(sw, obj, ns)
    
            If sw IsNot Nothing Then
                Return sw.ToString()
            Else
                Return ""
            End If
        End Function
    
    
        Public Shared Function Deserialize(Of T)(ByVal serializedXml As String) As T
            Dim xml As New System.Xml.Serialization.XmlSerializer(GetType(T))
            Dim sr As New IO.StringReader(serializedXml)
            Dim obj As T = CType(xml.Deserialize(sr), T)
    
            Return obj
        End Function
    

    【讨论】:

      猜你喜欢
      • 2017-01-24
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 2014-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多