Как я могу зафиксировать веб-ссылочный прокси та Visual Studio, сгенерированная для обработки зубчатых массивов?

Кажется, что существует известная ошибка в 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; }
    }
}

Который даже не позволяет блоку сериализации быть сгенерированным!

Не мог преобразовать Портфель типа. WebService.multiValuedAttribute к Портфелю. 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-элементов

Вторая вещь, которую я попробовал, состоит в том, чтобы дать deserializer различные инструкции:

[XmlArrayItemAttribute("attributes", typeof(multiValuedAttribute[]), Form=XmlSchemaForm.Unqualified)]
public multiValuedAttribute[][] assets { ... }

Таким образом, теперь я говорю этому, что каждый элемент в последовательности имеет тип multiValuedAttribute[]. Это неправильно, потому что это все еще смотрит на attributes элементы, которые имеют тип multiValuedAttribute (единственный, не массив). Это действительно работает однако, но теперь result.assets равно multiValuedAttribute[2][0] и я все еще не могу добраться до данных.

Что является следующим?

Я понятия не имею, который является, почему я записал это. Я не могу признать, что.NET не может использовать этот веб-сервис, потому что это имеет к.

5
задан Michiel van Oosterhout 6 August 2010 в 13:50
поделиться