【问题标题】:how to log http request body and headers while handle error in System.ServiceModel.Dispatcher.IErrorHandler如何在 System.ServiceModel.Dispatcher.IErrorHandler 中处理错误时记录 http 请求正文和标头
【发布时间】:2012-04-03 16:46:01
【问题描述】:

WCF 大师,

你可能已经知道我找不到的答案了……

假设我有一些 Web 服务 (WCF) 和一个客户端应用程序(基于 curl 库)。 有时在服务器站点上出现奇怪的错误:

OperationFormatter 无法反序列化 Message 中的任何信息,因为 Message 为空 (IsEmpty = true)。 System.Runtime.Serialization.SerializationException:OperationFormatter 无法反序列化 Message 中的任何信息,因为 Message 为空 (IsEmpty = true)。 来源:System.ServiceModel 堆栈跟踪: 在 System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(消息消息,对象 [] 参数) 重新抛出为: System.ServiceModel.CommunicationException:反序列化操作“...”的请求消息正文时出错。 OperationFormatter 无法反序列化 Message 中的任何信息,因为 Message 为空 (IsEmpty = true)。 来源:System.ServiceModel 堆栈跟踪: 在 System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(消息消息,对象 [] 参数) 在 System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(消息消息,对象 [] 参数) 在 System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(消息消息,对象 [] 参数) 在 System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(消息消息,对象 [] 参数) 在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) 在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin (MessageRpc& rpc) ...

在客户端站点上,我看到(在日志中)客户端发送请求并且请求不为空(有一些正文),但我想验证 WCF 是否从线路接收到此请求。 我怎样才能做到这一点? 理想情况下,我会在 System.ServiceModel.Dispatcher.IErrorHandler 等错误处理程序中记录传入请求(原始字节),否则在某处收集数据,然后在错误发生时记录它们(服务器上的某种低级 http 流量代理一边?)。

另一种解决方案是在服务器站点上安装 Wireshark,但我更愿意避免它,因为它发生在客户站点上,而且我无法访问她的机器。

谢谢!

【问题讨论】:

  • 您尝试过 WCF 消息记录吗? msdn.microsoft.com/en-us/library/ms730064.aspx
  • 还没有。据我了解,它会记录消息而不是原始请求。如果我没有找到另一种方法如何在我的日志文件中记录传入的数据,我会尝试一下。
  • 没错,它不会为您提供使用 wireshark 获得的那种原始 TCP 视图,但它应该向您显示 WCF 在抛出异常时试图反序列化的消息,您应该能够工作如果你有一个客户端和一个服务端日志要比较,从那里回来看看会发生什么。
  • 有一次我尝试使用 WCF 消息日志记录其他问题,但经过一些尝试后我放弃了。我发现如果我可以在服务器站点上打开/关闭它无需重新启动服务器并且可以以适合日志文件的格式将消息记录在我的日志文件中,这将是一个很好的工具,否则我会必须修改自动收集所有日志发送给我的反馈应用程序。也许从那以后发生了一些变化,我需要再试一次。

标签: wcf http


【解决方案1】:

我想,我找到了一个有点复杂的解决方案。如果您需要执行我在问题中提出的类似操作,您需要实现MessageEncoder 并通过MessageEncodingBindingElement 安装它。覆盖MessageEncoder 中的ReadMessage(...) 方法,您将可以访问包含原始传入正文的缓冲区。

【讨论】:

    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 2013-02-24
    • 2017-11-26
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    相关资源
    最近更新 更多