You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:44:33