C# 使用IDispatchMessageInspector记录WCF服务

C# 使用IDispatchMessageInspector记录WCF服务,c#,wcf,logging,idispatchmessageinspector,C#,Wcf,Logging,Idispatchmessageinspector,我正在尝试记录来自我的WCF服务的请求和响应。到目前为止,我所做的是: public class OutputMessageInspector : IDispatchMessageInspector { int lastLogId; public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { /

我正在尝试记录来自我的WCF服务的请求和响应。到目前为止,我所做的是:

public class OutputMessageInspector : IDispatchMessageInspector
{
    int lastLogId;

   public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
   {
       // Parse request & read required information
       // Insert request data into log tables
       // Set lastLogId to the id created above
   }

   public void BeforeSendReply(ref Message reply, object correlationState)
   {
       // Parse reply
       // Using lastLogId update the response column in database table
   }
}
一切正常,但我有一个顾虑:

AfterReceiveRequest
BeforeSendReply
必须同步工作,以便
BeforeSendReply
将更新正确的记录。我想到的情况是服务同时被多个客户呼叫,问题:

  • lastLogId
    是否会在多个应用程序之间混乱无序 请求和响应
  • 在SendReply之前的
    处进行此日志更新是否有效
    多个客户同时呼叫服务可以吗?如果有的话
    那么请给我一个解释,以确保我的心,如果没有那么
    请提供更好的解决方案

首先:WCF具有内置的功能,因此在推出自己的解决方案之前,可能值得研究一下

至于您的问题,通常您将IDispatchMessageInspector作为服务或端点行为应用,并挂接ApplyDispatchBehavior。在这里,您可能正在创建一个新的OutputMessageInspector,并将其添加到DispatchRuntime.MessageInspector集合中

在创建服务或端点时,行为只应用一次,因此您可以推断只有一个DispatchRuntime,并且您只创建一个MessageInspector,因此它将在所有请求/线程之间共享


在这种情况下,OutputMessageInspector需要是“线程安全的”。如果您在其中保持状态,您将需要同步对它的访问,以便它不会被扰乱。

首先:WCF具有内置的功能,因此在您推出自己的解决方案之前,可能值得研究一下

至于您的问题,通常您将IDispatchMessageInspector作为服务或端点行为应用,并挂接ApplyDispatchBehavior。在这里,您可能正在创建一个新的OutputMessageInspector,并将其添加到DispatchRuntime.MessageInspector集合中

在创建服务或端点时,行为只应用一次,因此您可以推断只有一个DispatchRuntime,并且您只创建一个MessageInspector,因此它将在所有请求/线程之间共享


在这种情况下,OutputMessageInspector需要是“线程安全的”。如果您在其中保留状态,您将需要同步对它的访问,以便它不会被扰乱。

我同意@Schneiders solution根据您的要求使用WCF日志记录

但是,要回答您的问题:

在BeforeSendReply上更新日志记录是否可以正常工作 多个客户端同时呼叫服务

不,不会的。
IDispatchMessageInspector的实例在调用之间共享

不使用成员属性,而是通过
IDispatchMessageInspector
上的
correlationState
支持特定于调用的数据。返回的任何对象都将作为
correlationState
传递给
BeforeSendReply()

换言之,类似的方法应该有效:

public class OutputMessageInspector : IDispatchMessageInspector
{
   public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
   {
       // Parse request & read required information
       // Insert request data into log tables
       // Set lastLogId to the id created above
       return lastLogId
   }

   public void BeforeSendReply(ref Message reply, object correlationState)
   {
       // Parse reply
       int lastLogId = (int)correlationState;
   }
}

我同意@Schneiders解决方案根据您的要求使用WCF日志记录

但是,要回答您的问题:

在BeforeSendReply上更新日志记录是否可以正常工作 多个客户端同时呼叫服务

不,不会的。
IDispatchMessageInspector的实例在调用之间共享

不使用成员属性,而是通过
IDispatchMessageInspector
上的
correlationState
支持特定于调用的数据。返回的任何对象都将作为
correlationState
传递给
BeforeSendReply()

换言之,类似的方法应该有效:

public class OutputMessageInspector : IDispatchMessageInspector
{
   public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
   {
       // Parse request & read required information
       // Insert request data into log tables
       // Set lastLogId to the id created above
       return lastLogId
   }

   public void BeforeSendReply(ref Message reply, object correlationState)
   {
       // Parse reply
       int lastLogId = (int)correlationState;
   }
}

实际上,我并不是只记录请求/响应,而是记录更多的东西,比如解析请求xml和请求者IP后的身份验证参数。实际上,我不是只记录请求/响应,而是记录更多的东西,比如解析请求xml和请求者IP后的身份验证参数。