You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# SOAP服务使用BinaryReader读取WebRequest返回数据异常求解

核心问题原因
  • 政务接口新增的两个端点返回的是**MTOM(消息传输优化机制)**格式的SOAP响应,属于带二进制附件的MIME多部分结构,并非纯XML报文,因此默认按纯XML解析的客户端会直接报错。
  • 你现有C#代码的核心错误是:将包含二进制PDF内容的整个响应流通过Encoding.Default.GetString()转换为字符串,编码转换过程会破坏二进制字节序列,导致PDF文件乱码损坏。
解决方案

C#服务端正确处理逻辑

你需要先拆分MIME多部分内容,分别处理XML报文和二进制附件,不要把整段响应转为字符串:

  1. 先读取响应头的Content-Type字段,提取MIME边界值。
  2. 使用.NET内置的MultipartMemoryStreamProvider拆分多部分响应流:
string soapResult = null;
byte[] attachmentBytes = null;
string attachmentName = null;

using (HttpWebResponse webResponse = (HttpWebResponse)httpRequest.EndGetResponse(asyncResult))
{
    if (request == "edoc/getDocument" || request == "edoc/downloadFile")
    {
        // 处理MTOM多部分响应
        var streamProvider = new MultipartMemoryStreamProvider();
        await webResponse.GetResponseStream().ReadAsMultipartAsync(streamProvider);
        
        // 第一部分是SOAP XML报文
        var xmlPart = streamProvider.Contents.FirstOrDefault(p => p.Headers.ContentType.MediaType == "application/xop+xml");
        if (xmlPart != null)
        {
            soapResult = await xmlPart.ReadAsStringAsync();
            // 这里可以解析XML拿到附件的文件名、Content-ID等信息
        }
        
        // 第二部分是PDF二进制附件
        var binaryPart = streamProvider.Contents.FirstOrDefault(p => p.Headers.ContentType.MediaType == "application/octet-stream");
        if (binaryPart != null)
        {
            attachmentName = binaryPart.Headers.ContentDisposition.FileName;
            attachmentBytes = await binaryPart.ReadAsByteArrayAsync();
            // 直接将attachmentBytes写入文件即可得到正常PDF,不要做编码转换
            File.WriteAllBytes(@"C:\保存路径\test.pdf", attachmentBytes);
        }
    }
    else
    {
        // 普通纯XML响应正常处理
        using (StreamReader rd = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
        {
            soapResult = rd.ReadToEnd();
        }
    }
}

如果是.NET Framework环境没有ReadAsMultipartAsync扩展,可以手动根据边界值拆分响应流,避免编码转换破坏二进制内容。

PHP客户端适配方案

PHP的SoapClient原生支持MTOM解析,初始化时开启对应配置即可自动识别附件,不需要手动捕获异常读取原始响应:

$client = new SoapClient("接口WSDL地址", [
    'soap_version' => SOAP_1_2,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
    'attachments' => SOAP_ATTACHMENTS_MTOM // 开启MTOM附件支持
]);
// 正常调用方法即可,返回结果会自动包含解析后的附件内容
$response = $client->Request($params);

内容的提问来源于stack exchange,提问作者Balázs Varga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:12:03