Создание сообщений WCF с несколькими пространствами имен

StackOverflow https://stackoverflow.com/questions/269096

  •  06-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь создать реализацию WSTransfer (я понимаю, что Roman Kiss уже написал ее для WCF, но на самом деле она не соответствует спецификациям)

В итоге я отказался от контрактов с данными в служебных контактах, потому что WSTransfer слабо связан;таким образом, каждое сообщение create выглядит как Message Create (запрос сообщения).

Это работает нормально, и все прекрасно, пока не придет время отправлять ответ.

Проблема, с которой я столкнулся, заключается в том, как строится ответ WSTransfer.Взяв create в качестве примера, ответ выглядит следующим образом

<wxf:ResourceCreated>
  <wsa:Address>....</wsa:Address>
  <wsa:ReferenceProperties>
    <xxx:MyID>....</xxx:MyId>
  </wsa:ReferenceProperties>
</wxf:ResourceCreated>

Как вы можете видеть, в ответном сообщении есть 3 различных пространства имен XML.

Теперь это достаточно просто, когда кто-то вовлечен;вы можете (даже если вы не раскрываете его) создать контракт с данными, установить значения и запустить его обратно

Message response = Message.CreateMessage(request.Version, 
            "http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse",
            resourceCreatedMessage);

Однако проблема возникает при настройке различных пространств имен для дочерних элементов в ответе;похоже, что datacontracts WCF этого не делают.Даже используя

[MessageBodyMember(Namespace="....")]

поскольку отдельные элементы в классе response, по-видимому, не вносят никаких изменений, все становится частью пространства имен, указанного для класса contract.

Итак, как мне применить разные пространства имен к отдельным элементам в сообщении WCF;либо через контракт, либо через какой-то другой джиговый покер?

Это было полезно?

Решение 2

Итак, следим за ответом джезелла;проблема с использованием XmlSerialization при создании сообщения вручную заключается в том, что дочерние элементы корневого каталога искажают имена своих элементов.Это происходит потому, что, несмотря на то, что операционный контракт помечен как [XmlSerializerFormat], при создании сообщения вручную используется DataContractSerializer.

Вы не можете передать XmlSerializer в Message.createMessage() потому что для этого требуется XmlObjectSerializer, которым XmlSerializer не является.

Итак, ответ, по-видимому, заключается в написании класса-оболочки для XmlSerializer, который имеет XmlObjectSerializer в качестве базового класса (вот пример) и передайте это в;вместе с классом хранения вашего сообщения.

К сожалению, это недостаточно умно для настройки префиксов в XML;таким образом, в итоге вы получаете такие сообщения, как

<ResourceCreated xmlns="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/">http://localhost:8731/Design_Time_Addresses/AddTests/WSTransfer/</Address>
  <ReferenceType xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/"></ReferenceType>

Но все это равнозначно.

Другие советы

В таком случае, когда вам нужен точный контроль над выводом XML, вы должны использовать XmlSerializer вместо сериализации DataContract или MessageContract. Вот дополнительная информация о том, как это сделать:

http://msdn.microsoft.com/en-us/library /ms733901.aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top