0

我正在尝试创建一个 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 的数据合同不这样做。即使使用

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

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

那么如何将不同的命名空间应用于 WCF 消息中的各个元素?是通过合同,还是通过其他一些诡计多端的游戏?

4

2 回答 2

0

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

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

于 2008-11-06T15:38:32.667 回答
0

所以跟进jezell的回答;手动创建消息时使用 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>

但这都是等价的。

于 2008-11-06T16:42:00.700 回答