在 .NET XML 反序列化中,如何允许多态使用 Array 类型?

时间:2023-03-30
本文介绍了在 .NET XML 反序列化中,如何允许多态使用 Array 类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

示例架构:

<complexType name="Dog">...</complexType>
<complexType name="Cat">...</complexType>

<complexType name="ArrayOfDog">
    <sequence>
        <element name="Dog" type="tns:Dog minOccurs="0" maxOccurs="unbounded" />
    </sequence>
</complexType>

<complexType name="Foo">
    <sequence>
        <element name="Bar" type="string"/>          
        <element name="Baz" type="anyType"/>
    </sequence>
</complexType>

通过 .NET 的 wsdl.exe 运行它会生成类似于以下的代码:

Running this through .NET's wsdl.exe generates code similar to the following:

[System.Xml.Serialization.XmlIncludeAttribute(typeof(Dog[]))]

public partial class Dog { ... }

public partial class Cat { ... }

public partial class Foo {
    private string barField;
    private object bazField;
}

似乎 wsdl.exe 试图变得聪明",并意识到我的 ArrayOfDog 实际上只是一个可以编码为 C# 数组的包装器类型.当在另一种数据类型中显式引用 ArrayOfDog 时,这可以正常工作.但是,当多态使用 ArrayOfDog(例如,作为 xsd:anyType 的替代)时,这会中断.它似乎崩溃了,因为 .NET 运行时对名为ArrayOfDog"的 complexType 一无所知——它基本上已经抛弃了这些信息,而只支持使用本机 C# 数组.

It appears that wsdl.exe is trying to be "smart" and realize that my ArrayOfDog is really just a wrapper type that can be encoded as a C# array. This works fine when ArrayOfDog is explicitly referenced in another data type. However, when ArrayOfDog is used polymorphically (e.g. as a substitution for xsd:anyType) this breaks. It appears to break because the .NET runtime knows nothing about the complexType named "ArrayOfDog" - it has basically thrown away this information in favor of just using native C# arrays.

示例 XML 文档 1:

Example XML document 1:

<Foo>
    <Bar>Hello</Bar>
    <Baz xsi:type="Cat">
        ...
    </Baz>
</Foo>

示例 XML 文档 2:

Example XML document 2:

<Foo>
    <Bar>Hello</Bar>
    <Baz xsi:type="ArrayOfDog">
        <Dog>...</Dog>
        <Dog>...</Dog>
    </Baz>
</Foo>

文档#1 被运行时正确反序列化.我得到了一个 Foo 类型的对象,其中包含 Bar 和 Baz 的正确反序列化字段.

Document #1 is deserialized correctly by the runtime. I get an object of type Foo with correctly deserialized fields for Bar and Baz.

文档 #2 被运行时错误地反序列化.我得到了一个 Foo 类型的对象,它具有正确反序列化的 Bar 字段,但对于 Baz 字段,我得到 System.XML.XMLNode[].我的猜测是因为运行时对名为ArrayOfDog"的实体的任何类型绑定一无所知.您可能认为 XmlInclude 指令XmlIncludeAttribute(typeof(Dog[]))"可以处理这个问题,但它似乎不起作用.

Document #2 is deserialized incorrectly by the runtime. I get an object of type Foo with a correctly deserialized field for Bar, but for the Baz field I get System.XML.XMLNode[]. My guess is because the runtime knows nothing about any type binding for an entity named "ArrayOfDog". You might think that the XmlInclude directive "XmlIncludeAttribute(typeof(Dog[]))" would handle this, but it doesn't appear to be working.

有人遇到过这个吗?

这里有一个优雅的解决方案吗?我正在考虑使用的解决方法是将我的ArrayOf"类型包装在另一种类型中,并将其包含在 xsd:anyType 的替换中.

Is there an elegant solution here? The workaround I'm thinking of using is to wrap my "ArrayOf" type in another type and include that in the subsitution for the xsd:anyType.

推荐答案

我认为这与多态无关.我认为这是 XML 序列化程序中的一个错误,假设任何名为ArrayOfDog"的类型,包含Dog"序列意味着代表一个 Dog[].作为对这一理论的测试,尝试将 WSDL 更改为使用名称BunchOfDogs",并查看这是否会更改客户端中的代理代码.

I don't think this has anything to do with polymorphism. I think this is a bug in the XML Serializer, assuming that any type named "ArrayOfDog", containing a sequence of "Dog" is meant to represent a Dog[]. As a test of this theory, try changing the WSDL to use the name "BunchOfDogs" instead, and see if this changes the proxy code in the client.

如果您想要 XML 中的多态性,那么 ArrayOfDog 和 Cat 都需要是相同基本类型的扩展(xsd:any 除外).如果是这种情况,那么我希望 .NET 将 Baz 生成为基本类型.

If you want polymorphism in XML, then both ArrayOfDog, and Cat, will need to be extensions of the same base type (other than xsd:any). If that were the case, then I'd expect .NET to generate Baz as being of the base type.

带有 xsd:any 的架构通常会导致问题.里面几乎可以有任何东西,有些组合根本没有意义.

Schemas with xsd:any cause problems just in general. There could be almost anything in there, and some combinations will simply not make sense.

您还没有说这个 Java 服务是否来自 Axis,或者它是什么版本.我已经看到 Axis 表现得好像 xsi:type 是有效模式的替代品.小心需要正确"使用 xsi:type 的模式.

You haven't said if this Java service is from Axis, or what version it is. I've seen Axis behave as though xsi:type were a substitute for a valid schema. Be careful with schemas that require "proper" use of xsi:type.

这篇关于在 .NET XML 反序列化中,如何允许多态使用 Array 类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:dataSet.GetXml() 不为 null 或空白列返回 xml 下一篇:LinqToXml 没有按预期处理 nillable 元素

相关文章