我正在将WCF客户端写入SOAP服务,该服务返回带有二进制数据的MIME多部分结果(实际上是PDF文件)。 它使用自定义消息编码器。
该服务似乎不介意我是否将请求设置为单部分格式,因此我能够返回结果。 从我所看到的结果有两个问题:
- 它似乎只返回多部分消息的第一部分。
- 我返回的数据无法通过我的自定义编码器解码。
我尝试使用 MTOM 绑定,但这弄乱了请求。 它无法在内容类型中添加"边界"参数,因此服务器无法理解请求。
我认为我想要的是一个基本的文本 SOAP 请求,但一个解码的 MTOM 风格的响应。 但是,我不知道如何设置它。
我找到的最接近的解决方案是:http://blogs.msdn.com/b/carlosfigueira/archive/2011/02/16/using-mtom-in-a-wcf-custom-encoder.aspx
但这似乎是对我的项目的一个非常侵入性的改变。
通了。 首先,当我说我只使用 MTOM 编码器获取多部分消息的第一部分时,我错了;我得到了整个东西。 我在调试器中查看它,底部一定在调试查看器中被剪掉了。 将其归咎于我缺乏手动查看和破译多部分消息的经验。
对于第二点,我所要做的就是在内容类型是多部分/相关并且一切正常时使用 MTOM 编码器。 如果您阅读了上面引用的文章,那么一切都是关于动态检测消息是多部分文本还是常规文本,并基于此选择合适的编码器。 本质上,它是一个自定义编码器,内置了文本编码器和 MTOM 编码器,并根据传入消息的内容类型来回切换。
我们的项目需要对响应消息进行一些后处理,然后再将其传递给主程序逻辑。 因此,我们以 XML 字符串的形式获取传入的 SOAP 内容,并对其执行一些 XML 操作。
这与本文中推荐的解决方案略有不同。 本文的解决方案中所需要的只是使用正确的编码器将消息读取到 System.ServiceModel.Channels.Message 中,然后返回该消息。 在我们的解决方案中,我们需要中断此过程并进行后处理。
为此,请在自定义编码器中实现以下内容:
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
//First, get the incoming message as a byte array
var messageData = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, messageData, 0, messageData.Length);
bufferManager.ReturnBuffer(buffer.Array);
//Now convert it into a string for post-processing. Look at the content-type to determine which encoder to use.
string stringResult;
if (contentType != null && contentType.Contains("multipart/related"))
{
Message unprocessedMessageResult = this.mtomEncoder.ReadMessage(buffer, bufferManager, contentType);
stringResult = unprocessedMessageResult.ToString();
}
else {
//If it's not a multi-part message, the byte array already has the complete content, and it simply needs to be converted to a string
stringResult = Encoding.UTF8.GetString(messageData);
}
Message processedMessageResult = functionToDoPostProccessing(stringResult);
return processedMessageResult;
}