Создание сообщений WCF с несколькими пространствами имен - PullRequest
0 голосов
/ 06 ноября 2008

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

Я закончил тем, что отказался от контрактов данных на контактах службы, потому что WSTransfer слабо связан; поэтому каждое сообщение создания выглядит как Сообщение создания (Запрос сообщения).

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

У меня проблема в том, как создается ответ 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);

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 06 ноября 2008

Итак, следуя ответу Джезелл; проблема с использованием 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>

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

0 голосов
/ 06 ноября 2008

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

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

...