W deserializacji XML .NET, w jaki sposób mogę pozwolić na polimorficzne użycie typów tablicowych?
Przykładowy schemat:
<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>
Uruchomienie tego za pomocą narzędzia wsdl.exe .NET generuje kod podobny do następującego:
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Dog[]))]
public partial class Dog { ... }
public partial class Cat { ... }
public partial class Foo {
private string barField;
private object bazField;
}
Wygląda na to, że wsdl.exe próbuje być „inteligentny” i zdaje sobie sprawę, że mój ArrayOfDog jest tak naprawdę tylko typem opakowania, który może być zakodowany jako tablica C #. Działa to dobrze, gdy ArrayOfDog jest jawnie przywoływany w innym typie danych. Jednakże, gdy ArrayOfDog jest używany polimorficznie (np. Jako podstawienie dla xsd: anyType), to się psuje. Wygląda na to, że się załamuje, ponieważ środowisko wykonawcze .NET nic nie wie o typie złożonym o nazwie „ArrayOfDog” - zasadniczo odrzuciło te informacje na korzyść używania rodzimych tablic C #.
Przykładowy dokument XML 1:
<Foo>
<Bar>Hello</Bar>
<Baz xsi:type="Cat">
...
</Baz>
</Foo>
Przykładowy dokument XML 2:
<Foo>
<Bar>Hello</Bar>
<Baz xsi:type="ArrayOfDog">
<Dog>...</Dog>
<Dog>...</Dog>
</Baz>
</Foo>
Dokument # 1 jest prawidłowo deserializowany przez środowisko wykonawcze. Dostaję obiekt typu Foo z poprawnie deserializowanymi polami dla Bar i Baz.
Dokument # 2 jest deserializowanynieprawidłowo przez środowisko wykonawcze. Dostaję obiekt typu Foo z poprawnie deserializowanym polem dla Bar, ale dla pola Baz otrzymuję System.XML.XMLNode []. Domyślam się, że środowisko wykonawcze nic nie wie o żadnym powiązaniu typu dla encji o nazwie „ArrayOfDog”. Można by pomyśleć, że dyrektywa XmlInclude „XmlIncludeAttribute (typeof (Dog []))” „poradzi sobie z tym, ale nie działa.
Czy ktoś to spotkał?
Czy jest tu eleganckie rozwiązanie? Rozwiązaniem, które zamierzam użyć, jest zawinięcie mojego typu „ArrayOf” w inny typ i uwzględnienie go w podstawieniu dla xsd: anyType.