使用IClientMessageInspector查看SOAP信封时出现编码字符异常
解决WCF ClientMessageInspector中SOAP体转义字符问题
我懂你遇到的麻烦了——用request.ToString()查看SOAP信封时,体里的XML元素全变成了<、>这种转义字符,根本没法直接看原始的XML结构对吧?这是因为ToString()方法在把Message对象转换成字符串时,会自动对XML特殊字符做实体编码,目的是避免字符串中的XML标签被解析错误,但这确实不是我们调试时想要的原始内容。
要获取未转义的原始SOAP内容,你需要借助MessageBuffer来创建消息的缓冲副本,这样既能读取完整的XML结构,又不会破坏原始的请求消息(毕竟Message是流式的,直接读取会消耗掉内容)。下面是两种常用的实现方式:
方式1:仅查看SOAP体内容
如果你只关心SOAP体部分,可以用GetReaderAtBodyContents()直接读取体的XML:
public object BeforeSendRequest(ref Message request, IClientChannel channel) { // 创建消息的缓冲副本,确保可以多次访问消息内容 using (var messageBuffer = request.CreateBufferedCopy(int.MaxValue)) { // 从缓冲中生成消息副本 var messageCopy = messageBuffer.CreateMessage(); // 获取SOAP体的XML读取器 using (var bodyReader = messageCopy.GetReaderAtBodyContents()) { // 读取完整的SOAP体XML字符串(无转义) string rawSoapBody = bodyReader.ReadOuterXml(); // 这里可以把rawSoapBody输出到调试窗口或者日志 System.Diagnostics.Debug.WriteLine(rawSoapBody); } // 恢复原始请求消息,避免影响后续发送 request = messageBuffer.CreateMessage(); } return null; }
方式2:查看完整的SOAP信封(包括头部和体)
如果需要查看整个SOAP信封的结构,可以用XmlWriter把整个消息写入字符串,这样能得到格式化的、未转义的完整XML:
public object BeforeSendRequest(ref Message request, IClientChannel channel) { using (var messageBuffer = request.CreateBufferedCopy(int.MaxValue)) { var messageCopy = messageBuffer.CreateMessage(); var soapBuilder = new StringBuilder(); // 配置XmlWriter,开启缩进让XML更易读 var writerSettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }; using (var xmlWriter = XmlWriter.Create(soapBuilder, writerSettings)) { messageCopy.WriteMessage(xmlWriter); xmlWriter.Flush(); // 完整的SOAP信封字符串 string rawSoapEnvelope = soapBuilder.ToString(); System.Diagnostics.Debug.WriteLine(rawSoapEnvelope); } request = messageBuffer.CreateMessage(); } return null; }
关键注意点
- 一定要用
CreateBufferedCopy()创建消息副本:因为WCF的Message是一次性的,直接读取原始消息会导致后续发送失败,缓冲副本可以让我们安全地读取内容,同时保留原始消息的完整性。 - 调试完成后记得清理调试输出代码,避免影响生产环境的性能。
内容的提问来源于stack exchange,提问作者Jade Cowan
相关产品推荐
相关产品推荐

