创建具有多个名称空间的WCF消息

时间:2008-11-06 15:24:28

标签: wcf datacontract

我正在尝试创建一个WSTransfer实现(我意识到Roman Kiss已经为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的datacontracts没有这样做。即使使用

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

对响应类中的各个元素似乎没有进行任何更改,所有内容都成为为合同类指定的命名空间的一部分。

那么如何将不同的命名空间应用于WCF消息中的各个元素;要么通过合同,要么通过其他一些jiggery pokery?

2 个答案:

答案 0 :(得分:0)

在这种情况下,当您需要精确控制XML输出时,应该使用XmlSerializer而不是DataContract或MessageContract序列化。以下是有关如何执行此操作的详细信息:

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

答案 1 :(得分:0)

跟随jezell的回答;手动创建消息时使用XmlSerialization的问题是root的子元素会损坏它们的元素名称。发生这种情况是因为尽管在手动创建消息时操作合同被标记为[XmlSerializerFormat],但仍使用了DataContractSerializer。

你不能将XmlSerializer传递给Message.CreateMessage(),因为它需要一个XmlObjectSerializer,XmlSerializer不是。

所以答案似乎是为XmlSerializer编写一个包装类,它将XmlObjectSerializer作为其基类(here's an example)并传入;以及你的留言课。

不幸的是,在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>

但它完全相同。