XMLSerializer为什么不序列化此类,即使我为派生类添加了XMLinclude属性?

发布于 2025-02-12 18:01:40 字数 2395 浏览 1 评论 0原文

问题

我正在尝试XML序列化“ profileserialize”类,但是在调用xssubmit.serialize(writer,obj) serialize in serialize 函数如下所示。

异常

message =“预期的类型profileformatnumber。请使用Xmlinclude或soapinclude属性来指定静态不知道的类型。”

我已经尝试过的

我尝试实现这些线程中提到的解决方案:

  1. 如何在xml中序列化派生类?
  2. 使用xmlSerializer序列化

Imports System
Imports System.Collections.Generic
Imports System.Collections
Imports System.IO
Imports System.Text
Imports System.Linq
Imports System.Reflection
Imports System.Xml.Serialization
Imports System.XML

' https://stackoverflow.com/questions/72856211/why-does-xmlserializer-fail-to-serialize-this-class-even-though-i-added-the-xmli

<XmlInclude(GetType(ProfileFormatNumber))>
Public Class ProfileFormat
    <XmlElement(ElementName:="e1")>
    Public Property Name As String = String.Empty      
End Class

Public Class ProfileFormatNumber
    Inherits ProfileFormat

    <XmlElement(ElementName:="e1")>
    Public Property Divider As Integer = 1
End Class

Public Class Serializer(Of T)
    Public Shared Function Serialize(ByVal obj As T) As String

            Dim xsSubmit As XmlSerializer = New XmlSerializer(GetType(T))

            Using sww = New StringWriter()

                Using writer As XmlTextWriter = New XmlTextWriter(sww) With {.Formatting = Formatting.Indented}
                    xsSubmit.Serialize(writer, obj)
                    Return sww.ToString() ' I would recommend moving this out of the inner Using statement to guarantee the XmlWriter is flushed and closed
                End Using

            End Using

    End Function
End Class
                
Public Module Module1
    Public Sub Main()
        Dim profileFormat = New ProfileFormatNumber With { .Name = "my name", .Divider = 111 }

        Dim xml2 = Serializer(Of ProfileFormat).Serialize(profileFormat)
        Console.WriteLine(xml2)

    End Sub
End Module

我的问题

我如何修改代码以正确使用&lt; xmlinclude(getType())&gt;属性?我尝试在多个位置添加它,但总是会收到相同的例外。

Problem

I am trying to XML serialize the class "ProfileSerialize" but I get this inner exception when calling xsSubmit.Serialize(writer, obj) in the Serialize function shown below.

Exception

Message = "The type ProfileFormatNumber was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."

What I already tried

I tried to implement the solutions mentioned in these threads:

  1. How to serialize derived classes in a Xml?
  2. Using XmlSerializer to serialize derived classes

Reproducible example

Imports System
Imports System.Collections.Generic
Imports System.Collections
Imports System.IO
Imports System.Text
Imports System.Linq
Imports System.Reflection
Imports System.Xml.Serialization
Imports System.XML

' https://stackoverflow.com/questions/72856211/why-does-xmlserializer-fail-to-serialize-this-class-even-though-i-added-the-xmli

<XmlInclude(GetType(ProfileFormatNumber))>
Public Class ProfileFormat
    <XmlElement(ElementName:="e1")>
    Public Property Name As String = String.Empty      
End Class

Public Class ProfileFormatNumber
    Inherits ProfileFormat

    <XmlElement(ElementName:="e1")>
    Public Property Divider As Integer = 1
End Class

Public Class Serializer(Of T)
    Public Shared Function Serialize(ByVal obj As T) As String

            Dim xsSubmit As XmlSerializer = New XmlSerializer(GetType(T))

            Using sww = New StringWriter()

                Using writer As XmlTextWriter = New XmlTextWriter(sww) With {.Formatting = Formatting.Indented}
                    xsSubmit.Serialize(writer, obj)
                    Return sww.ToString() ' I would recommend moving this out of the inner Using statement to guarantee the XmlWriter is flushed and closed
                End Using

            End Using

    End Function
End Class
                
Public Module Module1
    Public Sub Main()
        Dim profileFormat = New ProfileFormatNumber With { .Name = "my name", .Divider = 111 }

        Dim xml2 = Serializer(Of ProfileFormat).Serialize(profileFormat)
        Console.WriteLine(xml2)

    End Sub
End Module

My question

How do I need to modify my code to correctly use the <XmlInclude(GetType())> attribute? I tried adding it in multiple places but always receive the same exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风流物 2025-02-19 18:01:40

您的问题不是 > 。您的问题是,您正在尝试将profileformatnumberdivider and(从base类)name的两个属性分配给同一元素名称&lt; e1&gt;通过设置 noroflow noreferrer“> ”)&gt; 两者都在。即,如果能够序列化您的profile formatnumber as-is,则XML看起来像:

<ProfileFormat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="ProfileFormatNumber">
  <e1>my name</e1>
  <e1>111</e1>
</ProfileFormat>

但是xmlSerialializer不支持这一点(也许是因为在挑战中会有歧义),因此(略微难以理解的)错误抱怨元素名称e1已经存在:

The XML element 'e1' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.]

相反,请使用其他混淆的元素名称profileformatnumber.divider例如&lt; f1&gt;

<XmlInclude(GetType(ProfileFormatNumber))>
Public Class ProfileFormat
    <XmlElement(ElementName:="e1")>
    Public Property Name As String = String.Empty      
End Class

Public Class ProfileFormatNumber
    Inherits ProfileFormat

    <XmlElement(ElementName:="f1")>
    Public Property Divider As Integer = 1
End Class

demo fiddle

Your problem is not with XmlInclude. Your problem is that you are trying to assign the two properties of ProfileFormatNumber, Divider and (from the base class) Name, to the same element name <e1> by setting <XmlElement(ElementName:="e1")> on both. I.e. if were able to serialize your ProfileFormatNumber as-is, the XML would look like:

<ProfileFormat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="ProfileFormatNumber">
  <e1>my name</e1>
  <e1>111</e1>
</ProfileFormat>

However XmlSerializer does not support this (perhaps because there would be ambiguity in deserialization), hence the (slightly inscrutable) error complaining that the element name e1 is already present:

The XML element 'e1' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.]

Instead, use a different obfuscated element name for ProfileFormatNumber.Divider such as <f1>:

<XmlInclude(GetType(ProfileFormatNumber))>
Public Class ProfileFormat
    <XmlElement(ElementName:="e1")>
    Public Property Name As String = String.Empty      
End Class

Public Class ProfileFormatNumber
    Inherits ProfileFormat

    <XmlElement(ElementName:="f1")>
    Public Property Divider As Integer = 1
End Class

Demo fiddle here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文