【问题标题】:WCF IClientMessageInspector Logging Discrepancy Regarding ActionWCF IClientMessageInspector 记录有关操作的差异
【发布时间】:2015-07-13 10:24:00
【问题描述】:

我正在记录来自我的应用程序的传出 WCF Soap 请求,并发现我正在记录的内容与通过线路实际发送到服务器的内容之间存在差异。

这是我正在记录的内容:

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/myinterface</Action>
 </s:Header>
 <s:Body>
    <myinterface xmlns="http://tempuri.org/">
    ...

这是实际输出的内容(使用 WireShark 捕获):

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Body>
   <myinterface xmlns="http://tempuri.org/">
   ...

您会注意到 WireShark 捕获没有 Header 或 Action 元素。

我只是注意到这一点,因为我尝试通过 SoapUI 推送我记录的请求。

我正在使用此代码记录请求:

public class InspectorBehavior : IEndpointBehavior
{
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new WCFMessageInspector());
    }

还有:

public class WCFMessageInspector : IClientMessageInspector
{ 
    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
    {
        Log(request.ToString());

        return null;
    }

还有:

    client.Endpoint.Address = new System.ServiceModel.EndpointAddress(address);
    client.Endpoint.Behaviors.Add(new InspectorBehavior());

有没有人知道是否有一种方法可以准确地捕捉到正在发生的事情(逐字记录),而不需要如上所示的任何后期处理?

【问题讨论】:

    标签: wcf iclientmessageinspector


    【解决方案1】:

    您可以在App.config 中配置WCF Message Logging 以在传输级别记录消息。

    这应该尽可能晚地捕获消息:

    对于传出消息,记录会在消息离开用户代码之后立即发生,并且在消息传出之前立即发生。

    <system.diagnostics>
      <sources>
          <source name="System.ServiceModel.MessageLogging">
            <listeners>
                     <add name="messages"
                          type="System.Diagnostics.XmlWriterTraceListener"
                          initializeData="c:\logs\messages.svclog" />
            </listeners>
          </source>
        </sources>
    </system.diagnostics>
    
    <system.serviceModel>
      <diagnostics>
            <messageLogging 
             logEntireMessage="true" 
             logMalformedMessages="true"
             logMessagesAtServiceLevel="false" 
             logMessagesAtTransportLevel="true"
             maxMessagesToLog="1000"
             maxSizeOfMessageToLog="1000000"/>
      </diagnostics>
    </system.serviceModel>
    

    【讨论】:

    • 这不是我想要的。这会将所有内容写入一个大文本文件。我希望它仍然进入我的 BeforeSendRequest 方法,这样我就可以完全控制日志记录过程。
    • 我明白了。出于兴趣,您能否检查一下此日志记录方法是否与您的 IClientMessageInspector 记录的内容有所不同? (恕我直言,您遇到的问题非常奇怪。如果 Wireshark 显示的内容多于您在堆栈中较早捕获的内容,我可能会接受,但是在通往电线的途中 losing 标头听起来不正确... )
    • 是的,使用您的方法可以得到正确的结果。但它也将 XML 包装在一些额外的“包装器”元素中,作为其日志记录结构的一部分。我认为 WCF 正在将标头转换为 POST HTTP 请求中的实际 SOAP 操作(因此丢失了标头)。
    【解决方案2】:

    您可以通过 custom MessageEncoder 捕获确切的内容,与消息检查器 (IDispatchMessageInspector / IClientMessageInspector) 不同,它会查看原始字节内容,包括任何格式错误的 XML 数据。

    但是,实施这种方法有点困难。您必须将标准 textMessageEncoding 包装为自定义 binding element 并调整 config 文件以使用该自定义绑定。

    您还可以查看我在项目中的示例 - wrapping textMessageEncoding、日志记录 encoder、自定义绑定 elementconfig

    【讨论】:

      猜你喜欢
      • 2014-05-01
      • 1970-01-01
      • 2022-08-10
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多