問(wèn)題描述
示例架構(gòu):
<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>
通過(guò) .NET 的 wsdl.exe 運(yùn)行它會(huì)生成類似于以下的代碼:
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 試圖變得聰明",并意識(shí)到我的 ArrayOfDog 實(shí)際上只是一個(gè)可以編碼為 C# 數(shù)組的包裝器類型.當(dāng)在另一種數(shù)據(jù)類型中顯式引用 ArrayOfDog 時(shí),這可以正常工作.但是,當(dāng)多態(tài)使用 ArrayOfDog(例如,作為 xsd:anyType 的替代)時(shí),這會(huì)中斷.它似乎崩潰了,因?yàn)?.NET 運(yùn)行時(shí)對(duì)名為ArrayOfDog"的 complexType 一無(wú)所知——它基本上已經(jīng)拋棄了這些信息,而只支持使用本機(jī) C# 數(shù)組.
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 被運(yùn)行時(shí)正確反序列化.我得到了一個(gè) Foo 類型的對(duì)象,其中包含 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 被運(yùn)行時(shí)錯(cuò)誤地反序列化.我得到了一個(gè) Foo 類型的對(duì)象,它具有正確反序列化的 Bar 字段,但對(duì)于 Baz 字段,我得到 System.XML.XMLNode[].我的猜測(cè)是因?yàn)檫\(yùn)行時(shí)對(duì)名為ArrayOfDog"的實(shí)體的任何類型綁定一無(wú)所知.您可能認(rèn)為 XmlInclude 指令XmlIncludeAttribute(typeof(Dog[]))"可以處理這個(gè)問(wèn)題,但它似乎不起作用.
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.
有人遇到過(guò)這個(gè)嗎?
這里有一個(gè)優(yōu)雅的解決方案嗎?我正在考慮使用的解決方法是將我的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.
推薦答案
我認(rèn)為這與多態(tài)無(wú)關(guān).我認(rèn)為這是 XML 序列化程序中的一個(gè)錯(cuò)誤,假設(shè)任何名為ArrayOfDog"的類型,包含Dog"序列意味著代表一個(gè) Dog[].作為對(duì)這一理論的測(cè)試,嘗試將 WSDL 更改為使用名稱BunchOfDogs",并查看這是否會(huì)更改客戶端中的代理代碼.
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 中的多態(tài)性,那么 ArrayOfDog 和 Cat 都需要是相同基本類型的擴(kuò)展(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 的架構(gòu)通常會(huì)導(dǎo)致問(wèn)題.里面幾乎可以有任何東西,有些組合根本沒(méi)有意義.
Schemas with xsd:any cause problems just in general. There could be almost anything in there, and some combinations will simply not make sense.
您還沒(méi)有說(shuō)這個(gè) Java 服務(wù)是否來(lái)自 Axis,或者它是什么版本.我已經(jīng)看到 Axis 表現(xiàn)得好像 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.
這篇關(guān)于在 .NET XML 反序列化中,如何允許多態(tài)使用 Array 類型?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!