WCF 服务客户端:定制的肥皂信封未在线发送

Posted

技术标签:

【中文标题】WCF 服务客户端:定制的肥皂信封未在线发送【英文标题】:WCF service client: Customized soap envelope not being sent on the wire 【发布时间】:2014-06-02 19:30:10 【问题描述】:

我正在从 WCF 客户端调用第 3 方 Web 服务。问题是该服务需要特定的肥皂信封格式。

问题WCF Soap Format 处理同样的问题,建议的解决方案是编写一个CustomTextMessageEncoder。

我已经编写了一个自定义消息编码器,并在 WriteMessage 方法中完成了我的自定义格式化,该方法采用了主题 http://msdn.microsoft.com/en-us/library/ms751486(v=vs.110).aspx 中描述的 MSDN 示例编码器。

自定义格式删除了soap头内容并添加了一些第3方服务所需的命名空间前缀。

我可以看到在 VS 调试器中调用了编码器,并且它正在产生所需的输出:

        public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
    
        // code from MSDN example
        MemoryStream stream = new MemoryStream();
        XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
        message.WriteMessage(writer);
        writer.Close();

        // My customizing code
        var targetStream = new MemoryStream();
        FormatStreamToMirthFormat(stream, targetStream);

        // code from MSDN example
        // put the contents of the stream into a byte array
        byte[] messageBytes = targetStream.GetBuffer();
        int messageLength = (int)targetStream.Position;
        stream.Close();

        int totalLength = messageLength + messageOffset;
        byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
        Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);

        ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
        return byteArray;
    

我在 app.config 中配置了服务消息跟踪,以查看实际发送的内容,我遇到的问题是传入的肥皂信封似乎仍在网上发送(发送的信封是使用 basicHttpBinding)。

为什么发送的是传入的肥皂信封而不是我的自定义肥皂信封?

我注意到的另一件事是,如果我使用默认绑定“basicHttpBinding”,那么线路上的消息包含一个 Http 标头,后跟肥皂信封:

<HttpRequest xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
   <Method>POST</Method>
   <QueryString></QueryString>
   <WebHeaders>
       <VsDebuggerCausalityData>uIDPo+hLJO6ZB9hNt7/+pVZglrYAAAAAus8ogaD9Y0O0ThkjxtbdzBlxO8Yn2yBJggkv3BRx/qsACQAA</VsDebuggerCausalityData>
</WebHeaders>
</HttpRequest>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">..

而我的信息是从肥皂信封开始的。

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">

感谢您的帮助。

【问题讨论】:

【参考方案1】:

MessageEncoder 发生在 WCF 管道的后期,如果需要实现额外的安全要求,您将来可能会遇到问题。我会推荐一个 MessageFormatter。看看this article。

它解释了如何在服务器端执行此操作,但您也可以以类似的方式在客户端执行此操作,方法是覆盖 ApplyClientBehavior 而不是 ApplyDispatchBehavior,并派生 IClientMessageFormatter 而不是 IDispatchMessageFormatter。

【讨论】:

如果您查看该页面上的图表,您会发现只有在传输级别启用跟踪时才能看到 MessageEncoder 更改的消息,但我不确定是否记录发生在应用编码器之前或之后。 Fiddler 可能会帮助您了解您真正通过网络发送的内容。

以上是关于WCF 服务客户端:定制的肥皂信封未在线发送的主要内容,如果未能解决你的问题,请参考以下文章

HTTP 标头或 SOAP 标头中的 WCF 肥皂操作?

WCF 405 webmethod 未找到问题

如何在 wcf 中添加自定义肥皂标题?

WCF 客户端异常:无法识别的消息版本

从客户端请求中删除 Action (mustUnderstand)

客户端未收到 SignalR 消息