我正在尝试创建一个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?
答案 0 :(得分:0)
在这种情况下,当您需要精确控制XML输出时,应该使用XmlSerializer而不是DataContract或MessageContract序列化。以下是有关如何执行此操作的详细信息:
答案 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>
但它完全相同。