C# WCF服务客户端:自定义soap信封未在线发送

C# WCF服务客户端:自定义soap信封未在线发送,c#,.net,web-services,wcf,soap,C#,.net,Web Services,Wcf,Soap,我正在从WCF客户端调用第三方web服务。问题是服务需要特定的soap信封格式 这个问题涉及同样的问题,建议的解决方案是编写一个CustomTextMessageEncoder 我已经编写了一个自定义消息编码器,并按照主题中所述使用MSDN示例编码器在WriteMessage方法中完成了自定义格式设置 自定义格式将删除soap头内容,并添加第三方服务所需的一些命名空间前缀 我可以看到正在VS调试器中调用编码器,并且它正在生成所需的输出: public override Array

我正在从WCF客户端调用第三方web服务。问题是服务需要特定的soap信封格式

这个问题涉及同样的问题,建议的解决方案是编写一个CustomTextMessageEncoder

我已经编写了一个自定义消息编码器,并按照主题中所述使用MSDN示例编码器在WriteMessage方法中完成了自定义格式设置

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

我可以看到正在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;
    }
public-override-ArraySegment-WriteMessage(消息消息消息、int-maxMessageSize、BufferManager-BufferManager、int-messageOffset)
{
//来自MSDN示例的代码
MemoryStream stream=新的MemoryStream();
XmlWriter=XmlWriter.Create(流,this.writerSettings);
message.WriteMessage(编写器);
writer.Close();
//我的自定义代码
var targetStream=new MemoryStream();
FormatStreamToMirthFormat(流、目标流);
//来自MSDN示例的代码
//将流的内容放入字节数组
byte[]messageBytes=targetStream.GetBuffer();
int messageLength=(int)targetStream.Position;
stream.Close();
int totalLength=消息长度+消息偏移量;
byte[]totalBytes=bufferManager.TakeBuffer(totalLength);
复制(messageBytes,0,totalBytes,messageOffset,messageLength);
ArraySegment byteArray=新的ArraySegment(总字节数、messageOffset、messageLength);
乘火车返回;
}
我在app.config中配置了服务消息跟踪,以查看实际发送的内容,我遇到的问题是传入的soap信封似乎仍在通过线路发送(使用basicHttpBinding时发送的信封)

为什么要发送传入的soap信封而不是我的自定义soap信封

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

<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">..

邮递
uIDPo+hLJO6ZB9hNt7/+PVZGLRYAAAAAUS8OGAD9Y0O0HKJXTBDZBLXO8YN2YBJGKV3BRX/qsACQAA
..
而我的消息是从soap信封开始的

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


感谢您的帮助。

MessageEncoder在WCF管道中发生得较晚,如果需要实施其他安全要求,您将来可能会遇到问题。我建议使用MessageFormatter。看一看


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

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