WCF流式传输XML文件必须使用唯一Stream参数、TransferMode.Streamed绑定、禁用MTOM,并通过临时文件或Raw模式解析,否则将静默退入缓冲模式导致内存溢出。
WCF 服务接收 XML 文件,本质是接收二进制流(Stream),而非直接反序列化为 XDocument 或 XmlDocument —— 否则就失去大文件处理能力,且极易触发 OutOfMemoryException。流式传输不是“可选优化”,而是处理 >10 MB XML 文件的**唯一可行路径**。
WCF 的流式传输在编程模型层由契约强制约束,违反任一条件都会静默退回到缓冲模式(即整个 XML 加载进内存),且无警告。
Stream 参数或返回值必须是**唯一参数/返回值**:不能带其他 string fileName、int timeout 等辅助参数MessageHeader 或 URL 查询参数(HTTP 场景)传入[OperationContract] void UploadXmlFile(Stream xmlStream);
void UploadXmlFile(Stream xmlStream, string filename) —— 编译通过,但运行时失效仅改契约不够。默认所有绑定(如 BasicHttpBinding)都是 TransferMode.Buffered,此时即使参数是 Stream,WCF 仍会把整个 XML 读进内存再交给你的方法。
TransferMode.Streamed(双向流)、StreamedRequest(仅上传)、StreamedResponse(仅下载)BasicHttpBinding 和 CustomBin
ding 支持该属性;NetTcpBinding 同样支持maxReceivedMessageSize 必须同步调大(单位字节),否则超限直接抛 QuotaExceededException
WCF 流式传输的 Stream 是经过 SOAP 封装的(尤其启用 MTOM 时),它不是裸 XML 字节流 —— 直接丢给 XmlReader.Create(stream) 会报 Root element is missing 或乱码。
MessageEncoder 解包,或更实际地——**禁用 SOAP 封装,改用 Raw 模式**WebHttpBinding + [WebInvoke],并设置 BodyStyle = WebMessageBodyStyle.Bare
MessageEncoder 提取原始 XML 字节(复杂,仅必要时)Stream 后,先保存为临时文件,再用 XmlReader.Create(File.OpenRead(tempPath)) 安全解析MTOM(Message Transmission Optimization Mechanism)专为含二进制内容的 SOAP 消息设计,但它对纯文本 XML 文件**几乎无收益,反而增加解析负担**。
Stream 参数/返回值**(与前述规则重叠),且必须配合 text/xml 或 application/soap+xml 以外的 message/unknown MIME 类型Stream + WebHttpBinding 更轻量真正卡住多数人的不是“怎么写”,而是“为什么没生效”——WCF 流式传输失败时不会报错,只是悄悄吃掉内存。务必用 Process Explorer 观察服务进程私有字节数,上传 100MB 文件时若内存上涨超 150MB,说明流式未生效,立刻回查 TransferMode 和契约参数数量。