.NET发送含字节数组的SOAP请求遇CXF SoapFault错误,求原因
这种情况我之前踩过类似的坑,结合你说的「复制请求到SOAP UI就能正常发送」这个关键点,问题大概率出在你的.NET请求对二进制内容的处理或者请求头的配置上,具体可以从这几个方向排查:
二进制内容未做正确编码
你要发送的是文档的字节数组(比如PDF、Word这类二进制文件),如果直接把字节数组转成字符串插入SOAP消息,很可能会把二进制里的非XML字符(比如你遇到的'H')暴露在XML结构中,破坏了XML的语法规则——服务端期望XML开头是<,结果收到了二进制里的'H',自然报错。而SOAP UI会自动帮你把二进制数据转成base64编码字符串后再放入SOAP消息,这是XML传输二进制的标准方式。
建议:检查代码,确保把文档字节数组用Convert.ToBase64String(documentBytes)转成base64字符串后,再放到SOAP消息对应的节点里。请求头Content-Type配置错误
SOAP请求的Content-Type头是服务端解析的关键,比如标准的SOAP 1.1是text/xml; charset=utf-8,SOAP 1.2是application/soap+xml。如果你的.NET代码设置了错误的Content-Type(比如直接设成application/octet-stream),或者没有指定正确的字符集,服务端可能会错误地把二进制内容当成XML主体来解析。而SOAP UI会自动根据请求类型设置正确的Content-Type。
建议:用抓包工具(比如Fiddler)对比.NET请求和SOAP UI请求的请求头,重点对齐Content-Type、Content-Length这些字段。SOAP消息结构被意外破坏
可能你的代码在拼接SOAP消息时,出现了逻辑错误——比如把文档字节数组直接插入到了XML的prolog(也就是<?xml version="1.0"?>之前)的位置,导致服务端一接收就看到了'H'。而你复制到SOAP UI的是已经正确生成的完整XML消息,自然不会有这个问题。
建议:把.NET代码生成的原始请求内容(不要手动修改)抓出来,和SOAP UI里的请求内容做逐行对比,看二进制数据的插入位置是否正确。MTOM传输未启用(如果服务端支持的话)
如果服务端支持MTOM(Message Transmission Optimization Mechanism)传输二进制数据,那SOAP UI可能默认启用了MTOM,把二进制内容作为附件传输,避免了XML解析的问题。但你的.NET客户端可能没配置MTOM,导致二进制数据被当成普通文本嵌入XML。
建议:如果是用WCF客户端,在绑定配置里设置messageEncoding="Mtom";如果是手动构造请求,要按照MTOM的规范来组织消息结构。
你可以先从「对比.NET和SOAP UI的请求内容」入手,这是最快定位问题的方法。
内容的提问来源于stack exchange,提问作者Kacper Stelmach

