.NET 8.0下WCF Core Client如何发送未转义的CDATA字符串
解决.NET 8 WCF Core Client中strXML字段发送CDATA的问题
问题背景
在.NET 8项目中使用WCF Core Client调用服务时,自动生成的模型里strXML字段为string类型,发送请求时XML内容会被自动转义(如<代替<),但服务端期望接收包裹在CDATA中的原始XML数据,示例SOAP请求中strXML字段格式为:
<tem:strXML><![CDATA[<Info><Test><ID>1</ID><Message>Hello</Message></Test></Info>]]></tem:strXML>
已尝试的无效方案
- 将模型中
string替换为XmlElement,要么被序列化逻辑忽略,要么触发序列化异常 - 使用
XmlCDataSection替代string,框架不支持该类型的直接序列化,无效果 - 尝试通过WCF消息检查器重写SOAP请求体,.NET 8环境下该方案不可行
WCF框架内的可行解决方案
方案:自定义CDATA字符串类型实现序列化控制
通过实现IXmlSerializable接口,自定义一个支持CDATA序列化的字符串类型,替换自动生成模型中的string字段,让WCF在序列化时直接写入CDATA块。
- 定义自定义CDATA字符串类型
public class CDataString : IXmlSerializable { private string _value; public CDataString() { } public CDataString(string value) => _value = value; public string Value { get => _value ?? string.Empty; set => _value = value; } public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { if (reader.IsStartElement() && reader.Name == "strXML") { reader.Read(); if (reader.NodeType == XmlNodeType.CDATA) { _value = reader.Value; reader.Read(); } reader.ReadEndElement(); } } public void WriteXml(XmlWriter writer) { if (!string.IsNullOrEmpty(_value)) { writer.WriteCData(_value); } } // 隐式转换,方便和string类型互转 public static implicit operator string(CDataString cdata) => cdata?.Value; public static implicit operator CDataString(string value) => new CDataString(value); }
- 修改自动生成的模型字段
将原来的string strXML替换为自定义类型:
[System.ServiceModel.MessageBodyMemberAttribute(Namespace = "http://tempuri.org/")] public CDataString strXML;
- 确保服务契约使用XmlSerializer格式
在服务契约接口上添加[XmlSerializerFormat]特性(若原使用DataContractSerializer,切换为XmlSerializer以支持IXmlSerializable):
[ServiceContract(Namespace = "http://tempuri.org/")] [XmlSerializerFormat] public interface IYourServiceContract { [OperationContract] UpdateRecordResponse UpdateRecord(UpdateRecordRequest request); }
修改完成后,WCF客户端在序列化strXML字段时会自动将内容包裹在CDATA块中,无需手动处理原始SOAP数据,完全符合服务端的接收要求。
内容的提问来源于stack exchange,提问作者user2128898
相关产品推荐
相关产品推荐

