Кажется, есть известная ошибка в wsdl.exe, инструменте, который Visual Studio использует для генерации прокси веб-сервисов. С некоторыми схемами XSD инструмент генерирует классы, которые не могут быть десериализованы из XML.
Насколько я понимаю, это неприемлемо, но я не знаю, как это исправить.
Я опишу свой случай подробно, надеюсь, кто-нибудь сможет мне помочь с этим.
Схема
<!-- return type from the service operation -->
<xs:complexType name="listAssetsQueryResults">
<xs:sequence>
<xs:element name="assets" type="tns:asset" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- a sequence of attributes -->
<xs:complexType name="asset">
<xs:sequence>
<xs:element name="attributes" type="tns:multiValuedAttribute" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="multiValuedAttribute">
<!-- not relevant-->
</xs:complexType>
XML-ответ от веб-службы
Типичный ответ по этой схеме выглядит следующим образом:
<assets-query-result>
<assets>
<attributes>
<name>Keywords</name>
<values>Desert</values>
</attributes>
<attributes>
<name>Filename</name>
<values>Desert.jpg</values>
</attributes>
</assets>
<assets>...</assets>
<assets>...</assets>
</assets-query-result>
Использование типов в коде
Я бы ожидал, что смогу использовать типы CLR следующим образом:
result.assets[0].attributes[0].name
Вместо этого сгенерированный тип для результата выглядит следующим образом:
[SerializableAttribute()]
public partial class listAssetsQueryResults {
private multiValuedAttribute[][] assetsField;
[XmlArrayAttribute(Form=XmlSchemaForm.Unqualified, IsNullable=true)]
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets {
get { return this.assetsField; }
set { this.assetsField = value; }
}
}
Что даже не позволяет генерировать сборку сериализации!
Невозможно преобразовать тип
Portfolio.WebService.multiValuedAttribute
to Portfolio.WebService.multiValuedAttribute []
Исправление
1 - Изменение типа свойства и поля
Теперь одно из исправлений, которые я нашел в Интернете, - просто удалить одну пару скобок из типа сгенерированного свойства:
// No longer a jagged array, but this doesn't deserialize all data
public multiValuedAttribute[] assets;
Это позволяет создавать сборку сериализации, и она работает без исключений, за исключением того, что она не сериализует данные правильно, она «пропускает» список ресурсов и десериализует атрибуты первого элемента assets
. Так что это совсем не исправление, потому что с этим исправлением я не могу использовать данные. Для 700+ активов он дает result.assets
, равный multiValuedAttribute[2]
(2 элемента - это атрибуты имени и ключевых слов первого актива).
2 - указание типа XML-элементов
Второе, что я попробовал, это дать десериализатору разные инструкции:
[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute[]), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets { ... }
Итак, я говорю, что каждый элемент в последовательности имеет тип multiValuedAttribute[]
. Это неправильно, потому что он по-прежнему смотрит на attributes
элементы, которые имеют тип multiValuedAttribute
(один, а не массив). Однако он работает, но теперь result.assets
равен multiValuedAttribute[2][0]
, и я все еще не могу получить данные.
Что дальше?
Понятия не имею, поэтому я и написал это. Я не могу согласиться с тем, что .NET не может использовать этот веб-сервис, потому что он должен.