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

Posted

技术标签:

【中文标题】如何手动覆盖 WCF 客户端发送的 WSA To 标头【英文标题】:How can I manually override the WSA To header sent by a WCF client 【发布时间】:2012-05-12 15:55:50 【问题描述】:

我目前正在为我无法控制的 Java Web 服务编写 WCF 客户端。 WCF 似乎使用端点地址填充 WSA To 标头,但此 Web 服务需要不同的值。

我目前正在尝试手动设置值如下:

var binding = new CustomBinding();
binding.Elements.Add(GetSecurityElement());
binding.Elements.Add
(
    new TextMessageEncodingBindingElement
    (
        MessageVersion.Soap11WSAddressing10,
        Encoding.UTF8
    )
);
binding.Elements.Add(new HttpsTransportBindingElement());

var endpoint = new EndpointAddress
(
    new Uri("endpoint address"),
    new DnsEndpointIdentity("endpoint identity"),
    new AddressHeaderCollection()
);

var client = new Client(binding, endpoint);
client.Open();

using (new OperationContextScope(client.InnerChannel))

    OperationContext.Current.OutgoingMessageHeaders.To = new Uri("some other address");
    OperationContext.Current.OutgoingMessageHeaders.MessageId = new UniqueId("message id");
    var response = client.doSomething();

检查使用 Fiddler 生成和发送的请求,我可以看到 MessageID 标头已成功设置为“消息 ID”而不是默认的 urn:uuid:[some uuid],但 To 标头仍在设置为“端点地址”而不是“其他地址”。

还有其他方法可以覆盖标头值吗?

【问题讨论】:

您是否尝试过实现自定义消息检查器?这可能会有所帮助msdn.microsoft.com/en-us/library/aa717047.aspx @Suhas 我刚刚添加了一个 MessageInspector,除了 public object BeforeSendRequest(ref Message request, IClientChannel channel) return null; 。如果我在那里断点,request.Headers.To 确实设置为“其他地址”,但发送的请求仍然具有“端点地址”。 :( 【参考方案1】:

我已经使用 oulined here 的方法解决了这个问题。在代码中,解决方案是使用:

        var endpoint = new EndpointAddress
        (
            new Uri("wsa to address"),
            new DnsEndpointIdentity("endpoint identity"),
            new AddressHeaderCollection()
        );

设置 WSA To 标头的值。然后使用:

        client.Endpoint.Behaviors.Add(new ClientViaBehavior(new Uri("address")));

控制请求实际发送到的地址。

【讨论】:

【参考方案2】:

ClientVia 也可以添加到 .config 文件的 endpointBehavior 元素中:

<behaviors>
      <endpointBehaviors>
            <behavior name="someBehavior">
                  <clientVia viaUri="[URL of the actual host]" />
            </behavior>
      </endpointBehaviors>
</behaviors>
<client>
      <endpoint address="[Value of the wsa:To header]" ..... other settings ... />
</client>

请注意,您还需要使用正确的绑定设置 - 在 textMessageEncoding 或 wsHttpBinding 中具有正确 messageVersion 的 customBinding - 才能使用 WS-Addressing。

【讨论】:

以上是关于如何手动覆盖 WCF 客户端发送的 WSA To 标头的主要内容,如果未能解决你的问题,请参考以下文章

WCF寻址 - 删除WSA:TO元素

如何在 WCF 中使用 WS-Addressing 并设置 wsa:replyto 标头?

在“手动”发送肥皂消息时,我收到 WCF 的 AddressingNone 错误

WCF:如何手动记录原始 xml 消息内容?

如何强制 WCF 客户端发送客户端证书?

WCF 服务证书认证