我正在从WCF客户端调用第三方Web服务。问题是该服务需要特定的肥皂信封格式。
问题WCF Soap Format处理同样的问题,建议的解决方案是编写CustomTextMessageEncoder。
我编写了一个自定义消息编码器,并在WriteMessage方法中完成我的自定义格式化,采用MSDN示例编码器,如主题http://msdn.microsoft.com/en-us/library/ms751486(v=vs.110).aspx中所述。
自定义格式化会删除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;
}
我已经在app.config中配置了服务消息跟踪,以查看实际发送的内容以及我遇到的问题是看起来仍然在线路上发送传入的soap信封(当发送的信封时)使用basicHttpBinding)。
为什么传入的肥皂信封而不是我的自定义肥皂信封被发送?
我注意到的另一件事是,如果我使用默认绑定“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">..
而我的信息以肥皂信封开头。
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
感谢您的帮助。
答案 0 :(得分:0)
MessageEncoder在WCF管道的后期发生,如果需要实现其他安全要求,将来可能会遇到问题。我推荐一个MessageFormatter。看看this article。
它解释了如何执行此服务器端,但您也可以通过重写ApplyClientBehavior而不是ApplyDispatchBehavior,以及派生IClientMessageFormatter而不是IDispatchMessageFormatter来以类似的方式在客户端执行此操作。