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

如何从MTOM读取器(XmlDictionaryReader)中提取文件?

在C#/.NET中提取MTOM响应中的MIME附件并保存为文件

核心解决方案(手动处理MTOM流)

如果你已经拿到了MTOM响应的字节数组,不要尝试用ReadElementContentAsString读取二进制数据——MTOM的附件是通过XOP(XML二进制优化打包)以MIME分块传输的,需要识别xop:Include元素来提取附件:

using System;
using System.IO;
using System.Xml;

public void SaveMtomAttachment(byte[] mtomResponseBytes, string outputPath)
{
    using var responseStream = new MemoryStream(mtomResponseBytes);
    // 创建MTOM读取器,设置最大配额避免读取大文件时受限
    using var mtomReader = XmlDictionaryReader.CreateMtomReader(
        responseStream, 
        XmlDictionaryReaderQuotas.Max
    );

    // 遍历XML节点,定位xop:Include元素
    while (mtomReader.Read())
    {
        // 匹配xop:Include元素(注意命名空间必须正确)
        if (mtomReader.IsStartElement("Include", "http://www.w3.org/2004/08/xop/include"))
        {
            // 读取附件的Content-ID(可选,用于区分多附件场景)
            string contentId = mtomReader.GetAttribute("href").TrimStart("cid:".ToCharArray());
            
            // 读取二进制附件数据,自动解码MIME分块内容
            mtomReader.ReadStartElement();
            byte[] attachmentBytes = mtomReader.ReadContentAsBase64();
            
            // 写入文件
            File.WriteAllBytes(outputPath, attachmentBytes);
            break; // 单附件场景找到后退出循环,多附件则去掉break并处理每个Include
        }
    }
}

关键注意事项

  1. 不要直接读取标签内容:如果你的响应XML中<Data>节点包含的是xop:Include而非内嵌Base64,直接读字符串会得到XML片段而非二进制数据,必然报错。
  2. 必须匹配xop命名空间:xop:Include的命名空间固定为http://www.w3.org/2004/08/xop/include,忽略命名空间会导致无法识别该元素。
  3. 处理多附件:如果响应包含多个附件,去掉代码中的break,根据每个xop:Include的href属性(Content-ID)生成不同的文件名保存。

更简便的WCF客户端场景

如果是通过WCF调用服务并接收MTOM响应,直接在消息契约中标记XmlMimeType属性,WCF会自动解析附件:

using System.ServiceModel;
using System.Xml.Serialization;

// 定义消息契约
[MessageContract(IsWrapped = false)]
public class FileDownloadResponse
{
    [MessageBodyMember(Name = "FileData", Namespace = "YourServiceNamespace")]
    [XmlMimeType("application/octet-stream")] // 指定MIME类型
    public byte[] Attachment { get; set; }
}

// 调用服务后直接保存
var client = new YourServiceClient();
var response = client.DownloadFile();
File.WriteAllBytes("output.file", response.Attachment);

内容的提问来源于stack exchange,提问作者Max von der Mühle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:52:48