4

我正在将 WCF 客户端写入 SOAP 服务,该服务返回带有二进制数据(实际上是 PDF 文件)的 mime 多部分结果。它使用自定义消息编码器。

如果我将请求设为单部分格式,该服务似乎并不介意,因此我可以返回结果。从我所看到的结果来看,有两个问题:

  • 它似乎只返回多部分消息的第一部分。
  • 我的自定义编码器无法解码我返回的数据。

我曾尝试使用 MTOM 绑定,但这会弄乱请求。未能在内容类型中添加“边界”参数,因此服务器无法理解请求。

我想我想要的是一个基本的文本 SOAP 请求,但响应解码为 MTOM 样式。但是,我不知道如何设置它。

我找到的最接近的解决方案是:http: //blogs.msdn.com/b/carlosfigueira/archive/2011/02/16/using-mtom-in-a-wcf-custom-encoder.aspx

但这对我的项目来说似乎是一个非常具有侵略性的改变。

4

1 回答 1

5

我想通了。首先,当我说我只使用 MTOM 编码器获取多部分消息的第一部分时,我是不正确的;我得到了整个事情。我在调试器中查看它,底部一定在调试查看器中被剪掉了。将其归咎于我缺乏手动查看和破译多部分消息的经验。

对于第二点,我所要做的就是在 Content-Type 是多部分/相关并且一切正常时使用 MTOM 编码器。如果您阅读了上面引用的文章,这就是动态检测消息是多部分文本还是常规文本,并据此选择合适的编码器。本质上,它是一个自定义编码器,其中内置了文本编码器和 MTOM 编码器,并根据传入消息的内容类型来回切换。

我们的项目需要在将响应消息传递给主程序逻辑之前对其进行一些后期处理。因此,我们将传入的 SOAP 内容作为 XML 字符串获取,并对其进行一些 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;
}
于 2012-08-17T16:34:24.517 回答