vb.net 序列化包含对象列表的对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25204762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 18:00:46  来源:igfitidea点击:

Serialize an object that contains a list of objects

vb.netserializationxmlserializer

提问by Rob Heijligers

I'v build a NotInheritable Serilizer that serilizes all my classes and list of classes with success. Until I'v build a list of class that contains a list of classes. I'm getting the runtime Exeption: There was an error generating the XML document. resulting in a perfectly empty XML :(

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

These are my classes to serilize:

这些是我要序列化的课程:

<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

And the serializer:

和序列化器:

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

And this is the call:

这是电话:

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

If i comment the list in StatisticItem everything works.

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

I think if I Implement IXmlSerializable in StatisticItem I can tell the serializer how to work to make it work, but I see other code example on the internet where this works without all this effort and I prefer a clean solution, that is about the same as all my other classes.

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

Hope one of you guys can help me out

希望你们中的一位能帮助我

采纳答案by Rob Heijligers

Yes solved!, To be honest I changed so much small things that I still don't know what the cause was. Maybe that there were still some private members. Anyway, maybe the code can be useful for anyone:

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

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

Serializer:

序列化器:

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

The call of the Serializer:

Serializer 的调用:

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

The call of the deSerializer:

deSerializer 的调用:

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

回答by jrjensen

I needed to do this also but create a string instead. Here's my solution:

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

    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