2012-04-27 58 views
0

我需要在IClientMessageInspector中做一些操作日志记录,并知道操作何时开始并结束至关重要。但我不能得到AfterReceiveReply单向操作,这是明确的原因。有没有办法知道在BeforeSendRequest超载中操作是单向的,所以我可以忽略它?IClientMessageInspector检测单向操作

回答

1

检查器本身没有任何信息(或传递给BeforeSendRequest的消息),但可以将此信息传递给检查器,并使用消息操作来查看操作是否是单向的。

public class StackOverflow_10354828 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
     [OperationContract(IsOneWay = true)] 
     void Process(string input); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) 
     { 
      return text; 
     } 
     public void Process(string input) { } 
    } 
    class MyInspector : IClientMessageInspector 
    { 
     public HashSet<string> oneWayActions; 

     public MyInspector(ServiceEndpoint endpoint) 
     { 
      this.oneWayActions = new HashSet<string>(); 
      foreach (var operation in endpoint.Contract.Operations) 
      { 
       if (operation.IsOneWay) 
       { 
        oneWayActions.Add(operation.Messages[0].Action); 
       } 
      } 
     } 

     public void AfterReceiveReply(ref Message reply, object correlationState) 
     { 
      Console.WriteLine("In AfterReceiveReply"); 
     } 

     public object BeforeSendRequest(ref Message request, IClientChannel channel) 
     { 
      Console.WriteLine("In BeginSendRequest"); 
      if (this.oneWayActions.Contains(request.Headers.Action)) 
      { 
       Console.WriteLine("This is a one-way operation"); 
      } 

      return null; 
     } 
    } 
    class MyBehavior : IEndpointBehavior 
    { 
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
     { 
     } 

     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
     { 
      clientRuntime.MessageInspectors.Add(new MyInspector(endpoint)); 
     } 

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
     { 
     } 

     public void Validate(ServiceEndpoint endpoint) 
     { 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); 
     factory.Endpoint.Behaviors.Add(new MyBehavior()); 
     ITest proxy = factory.CreateChannel(); 
     proxy.Echo("Hello"); 
     Console.WriteLine(); 

     proxy.Process("world"); 
     Console.WriteLine(); 

     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
1

回复自己,一个瞬间我这样做:

布尔isOneWay = request.Headers.ReplyTo == NULL;