如何让System.ServiceModel.ClientBase发送未转义的纯XML?
解决WCF ClientBase发送纯XML不被转义的问题
这种情况我之前也碰到过——WCF默认的序列化会把字符串里的XML内容转义成实体字符,导致目标系统无法识别。好在有几种可靠的方法可以解决:
方法1:使用XmlSerializerFormat替代默认序列化
WCF默认用DataContractSerializer,它会把字符串类型的字段当成普通文本处理,自然会转义XML特殊字符。我们可以改用XmlSerializer,通过属性控制直接输出纯XML结构。
步骤:
- 定义强类型的请求模型,用
XmlElement属性映射XML节点:
[XmlRoot("RootElementName")] public class PODRequest { [XmlElement("GetPODsList")] public GetPODsListContainer GetPODsList { get; set; } } public class GetPODsListContainer { [XmlElement("GetPODList_In")] public GetPODListInput Input { get; set; } } public class GetPODListInput { [XmlElement("LanguageCode")] public string LanguageCode { get; set; } [XmlElement("WebUser")] public Guid WebUser { get; set; } // 补充你的其他字段 }
- 在服务契约上添加
[XmlSerializerFormat]特性,指定使用XmlSerializer:
[ServiceContract] [XmlSerializerFormat(Style = OperationFormatStyle.Document)] public interface IPODService { [OperationContract(Action = "YourTargetActionUri")] void SubmitPODRequest(PODRequest request); }
- 用ClientBase生成客户端后,直接实例化模型并传入请求——此时序列化出来的XML就是纯结构,不会被转义。
方法2:手动构建XML消息体(适合动态内容)
如果你的XML结构是动态的,不方便定义强类型模型,可以直接构建XML文档,绕过默认序列化逻辑:
// 手动构造目标XML var rawXml = @"<GetPODsList> <GetPODList_In> <LanguageCode>nl</LanguageCode> <WebUser>80AA0BF6-E773-4BD7-B2A1-2F0849848520</WebUser> <!-- 其他字段 --> </GetPODList_In> </GetPODsList>"; var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(rawXml); // 创建自定义Message var message = Message.CreateMessage( MessageVersion.Soap11, "YourTargetActionUri", xmlDoc.DocumentElement); // 使用ClientBase发送消息 using (var client = new PODServiceClient()) { var channel = client.InnerChannel; channel.Send(message); }
这种方式直接把XML节点作为消息体发送,完全不会被转义。
方法3:用XmlText属性处理字符串类型的Body
如果你的请求模型里Body是字符串类型,想直接输出纯XML,可以给该字段加上[XmlText]属性,同时配合XmlSerializerFormat:
[DataContract] public class RequestWrapper { [DataMember(Name = "Body")] [XmlText] public string RawXmlBody { get; set; } } // 服务契约同样需要添加XmlSerializerFormat [ServiceContract] [XmlSerializerFormat] public interface IWrapperService { [OperationContract] void SendRawRequest(RequestWrapper request); }
这样当你把纯XML字符串赋值给RawXmlBody时,XmlSerializer会直接输出它的内容,而不是转义后的字符串。
关键原理
DataContractSerializer的设计目标是跨平台的数据交换,它会严格处理字符串的转义;而XmlSerializer更贴近传统XML序列化场景,允许通过属性直接控制XML节点的生成逻辑,这就是解决问题的核心。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

