为啥 WCF 删除了我的回复消息中的 wsa:To 标头?

Posted

技术标签:

【中文标题】为啥 WCF 删除了我的回复消息中的 wsa:To 标头?【英文标题】:Why is the wsa:To header in my reply message removed by WCF?为什么 WCF 删除了我的回复消息中的 wsa:To 标头? 【发布时间】:2017-07-30 19:33:05 【问题描述】:

我有一个带有IDispatchMessageInspectorBeforeSendReply 方法的WCF 服务,它修改了消息的WS-Addressing 标头。这适用于所有标题,除了 wsa:To,它正在从回复中删除...

public void BeforeSendReply(ref Message reply, object correlationState)

    reply.Headers.To = new Uri("urn:something:something:something"); // Why won't this show up in the response?

    reply.Headers.From = new EndpointAddress("urn:blabla:blabla");
    reply.Headers.MessageId = MessageIDHelper.CreateNew();
    reply.Headers.ReplyTo = new EndpointAddress(Definitions.WSA_REPLYTO_ANONYMOUS);
    reply.Headers.Action = Definitions.WSA_ACTION_SOMETHING_SOMETHING;

这会导致:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://xxx.xx/xxx/Messages/1/Send</a:Action>
    <a:RelatesTo>SOME_ID_WHATEVER</a:RelatesTo>
    <a:From>
      <a:Address>urn:xxx.xx:xxx:xxx</a:Address>
    </a:From>
    <a:MessageID>urn:uuid:083b5fb7-ff45-4944-b881-b4c590577408</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  ...
</s:Envelope>

即使result.ToString()(结果 = Message 类型)给了我:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://xxx.xx/xxx/Messages/1/Send</a:Action>
    <a:RelatesTo>SOME_ID_WHATEVER</a:RelatesTo>
    <a:To s:mustUnderstand="1">urn:xxx.xx:xxx:xxx<a:To>
    <a:From>
      <a:Address>urn:xxx.xx:xxx:xxx</a:Address>
    </a:From>
    <a:MessageID>urn:uuid:083b5fb7-ff45-4944-b881-b4c590577408</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  ...
</s:Envelope>

那么...为什么wsa:To 标题从我的回复中被删除了?

【问题讨论】:

【参考方案1】:

TransportBindingElement.ManualAddressing 属性的文档提供了有关寻址行为的一些信息。 IE。如果 ManuelAddressing 的值设置为 false,则发送通道将配置为通道上 To: 收件人的 EndpointAddress 应用于传出消息。这意味着频道对 To: 标头的值有发言权。

现在,BeforeSendReply() 在服务级别修改消息的内容,然后将其移交给通道进行传输。因此,如果 ManuelAddressing 的值为 false,则通道会在消息头中设置自己的 To: 值。

只要 ManuelAddressing 的值设置为 true,通道就会假定消息已被寻址,并且不会添加任何附加信息。 为了将 ManuelAddressing 设置为 True,可以在 web.config 文件中创建自定义绑定:

<customBinding>
  <binding name="customBinding_manualAddressingEnabled">
    <textMessageEncoding />
    <httpTransport manualAddressing="true"/>
  </binding>
</customBinding>

【讨论】:

以上是关于为啥 WCF 删除了我的回复消息中的 wsa:To 标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何手动覆盖 WCF 客户端发送的 WSA To 标头

WCF消息压缩

为回复消息创建 WCF 寻址标头

为啥 Linq-to-sql 错误地删除了我的联合中的字段?

软件导致连接中止。回复错误:连接无效

WCF 捕获异常“服务器没有提供有意义的回复..”