Необязательное перечисление с клиентом WCF - PullRequest
4 голосов
/ 01 февраля 2012

Я работаю с веб-службой внешнего поставщика, которая, по-видимому, реализована на Java (я полагаю, Apache Axis), и я использую ее с клиентом WCF.Для некоторых операций требуются входные параметры перечисления типов.Проблема в том, что они хотят, чтобы перечисления передавались только в определенных случаях.Элементы не помечены как nillable в WSDL.Так как они являются перечислениями, мой клиент WCF всегда будет передавать значение по умолчанию, даже если оно не указано.Такое поведение вызывает внутреннюю ошибку в их службе.

Есть мысли о том, как решить эту проблему?Предпочтительно, это будет решение, которое не потребует ручной модификации прокси-сервера, поскольку это может привести к путанице, если другой разработчик будет генерировать его самостоятельно в будущем.

Конкретный элемент указан в WSDL следующим образом

<xs:complexType name="complexTypeName">
<xs:sequence>
    <!-- More Stuff Here-->
    <xs:element minOccurs="0" name="parameterName" type="tns:parameterName" />
    <!-- More Stuff Here-->
</xs:sequence>
</xs:complexType>

<!-- . . . -->

<xs:simpleType name="parameterName">
  <xs:restriction base="xs:string">
    <xs:enumeration value="ONLY_AVAILABLE_VALUE" />
  </xs:restriction>
</xs:simpleType>

Svcutil переводит это как

[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://vendorwebservicenamespace.com/")]
public enum parameterName
{   
    /// <remarks/>
    ONLY_AVAILABLE_VALUE,
}

РЕДАКТИРОВАТЬ: После еще нескольких исследований, похоже, что svcutil должен обычно генерировать опциональнопараметры (minOccurs = 0) с дополнительным bool fieldNameSpecified , позволяющим вызывающей стороне указывать, нужно ли сериализовать поле (это задокументировано здесь , здесь и здесь ).

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

[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://vendorservicenamespace.com/", Order=23)]
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Namespace.parameterName parameterName;

Когда я пытаюсь вручную добавить соответствующие fieldNameSpecified метод, похоже, он не влияет на сериализацию (т. Е. Параметр все еще присутствует в мыльном сообщении).

В момент tмне интересно,

  1. Почему svcutil не включает fieldNameSpecified параметры?
  2. Почему не кажется, что добавление параметра вручную работает?
  3. Есть ли какие-либо другие обходные пути для этой проблемы?

РЕДАКТИРОВАТЬ: После еще одного исследования я определил, что часть проблемы заключается вкоторый написан WSDL.WSDL поставщика не соответствует справочнику схемы для DataContractSerializer.Из-за этого svcutil возвращается к XmlSerializer.

Проблема заключается в том, что он все еще генерирует контракты сообщений для методов, но не контракты данных.По-видимому, это приводит к проблеме для любых типов, которые по умолчанию не могут быть обнуляемыми, в том, что они не могут быть исключены из сообщения (кто-нибудь может это проверить?).Какова бы ни была причина, метод parameterNameSpecified для XmlSerializer, по-видимому, игнорируется, когда параметр помечен MessageBodyMemberAttribute (не уверен почему?)

Единственный способ, которым я смог обойтиэто происходит при использовании опции /wrapped с svcutil.Это приводит к тому, что контракты сообщений отделяются от самих разделенных параметров.В этом случае svcutil генерирует , генерирует parameterNameSpecified методы, и XmlSerializer соответствует им.

1 Ответ

3 голосов
/ 03 февраля 2012

После изучения проблемы единственное решение, которое мне удалось найти, - это создать прокси с помощью параметра / wrapped в svcutil.Как упоминалось выше в вопросе, это добавляет дополнительный уровень абстракции и позволяет контрактам сообщений существовать на уровне выше параметров.В этом случае XmlSerializer генерирует свойства fieldNameSpecified и соответствует им.

...