WCF客户端发送含CDATA的XML字符串后CDATA丢失问题排查
问题原因
WCF处理SOAP请求时会自动解析传入的XML内容。CDATA是XML的语法结构,作用是标记无需转义的文本,当XML被解析后,CDATA的包裹标记会被剥离,仅保留内部文本——这就是服务端接收到的字符串里没有<![CDATA[]]>的原因。而&这类XML特殊字符原本依赖CDATA避免转义,标记被剥离后,未转义的&就会触发反序列化异常。
解决方案
方案1:将参数类型改为XmlNode或XElement
如果要完整保留XML结构(包括CDATA标记),可以把服务方法的参数从string改为XmlNode或XElement,WCF会直接传递原始XML节点,不会剥离CDATA:
// 使用XmlNode的示例 public MyResponse GetContract(XmlNode xml) { // 转换为字符串即可获取带CDATA的原始内容 string rawXml = xml.OuterXml; // 后续反序列化逻辑 }
// 使用XElement的示例 public MyResponse GetContract(XElement xml) { string rawXml = xml.ToString(); // 后续逻辑 }
方案2:对XML字符串转义后再发送
如果必须使用string类型参数,可在客户端发送前对整个XML字符串做XML转义,让WCF将其当作纯文本处理,不解析内部XML结构:
原始XML:
<?xml version="1.0" encoding="utf-16" ?> <Contract> <ContractData> <Name><![CDATA[M&M's]]></Name> </ContractData> </Contract>
转义后内容:
<?xml version="1.0" encoding="utf-16" ?> <Contract> <ContractData> <Name><![CDATA[M&M's]]></Name> </ContractData> </Contract>
服务端接收到转义后的字符串后,再执行反转义操作,就能恢复包含CDATA的原始XML。
方案3:修改绑定配置禁用XML解析
通过修改WCF绑定的消息编码方式,让请求内容以纯文本形式传递,避免自动解析XML。例如使用webHttpBinding并配置相关参数:
服务端配置文件:
<system.serviceModel> <bindings> <webHttpBinding> <binding name="RawXmlBinding"> <security mode="None" /> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" /> </binding> </webHttpBinding> </bindings> <services> <service name="YourServiceNamespace.YourService"> <endpoint address="" binding="webHttpBinding" bindingConfiguration="RawXmlBinding" contract="YourServiceNamespace.IYourService" behaviorConfiguration="RawBehavior" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="RawBehavior"> <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml" /> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
服务契约调整:
[ServiceContract] public interface IYourService { [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)] MyResponse GetContract(string xml); }
这种配置下,WCF不会解析传入的XML内容,会直接将原始字符串传递到服务端方法中。
内容的提问来源于stack exchange,提问作者Alexander Groshev
相关产品推荐
相关产品推荐

