2011-09-20 90 views
1

我正在使用我的WCF服務與我不控制的外部Web服務進行通信。現在,我想爲被調用的操作添加一個行爲,以便每當無法與服務通信時,就應該通過特定的存儲過程將某些內容記錄到數據庫中(在這種情況下,沒有NLog/Log4Net,它是真的是一個存儲過程)。但是,我不想在每個調用服務的方法中編寫代碼,所以我認爲一個行爲應該更合適。我該如何去做到這一點?從客戶端擴展WCF服務調用

回答

2

您可以在您的客戶端中使用IClientMessageInspector,它在接收到回覆後收到呼叫時會檢查回覆是否成功(即故障)。如果不是,可以正確記錄。下面的代碼顯示了一個客戶端消息檢查器的例子。你可以在http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx找到更多關於郵件檢查員的信息。

public class StackOverflow_7484237 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) 
     { 
      if (text == "throw") 
      { 
       throw new ArgumentException("This will cause a fault to be received at the client"); 
      } 
      else 
      { 
       return text; 
      } 
     } 
    } 
    public class MyInspector : IEndpointBehavior, IClientMessageInspector 
    { 
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
     { 
     } 

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

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

     public void Validate(ServiceEndpoint endpoint) 
     { 
     } 

     public void AfterReceiveReply(ref Message reply, object correlationState) 
     { 
      if (reply.IsFault) 
      { 
       Console.WriteLine("Log this fault: {0}", reply); 
      } 
     } 

     public object BeforeSendRequest(ref Message request, IClientChannel channel) 
     { 
      return null; 
     } 
    } 
    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"); 

     var factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); 
     factory.Endpoint.Behaviors.Add(new MyInspector()); 
     var proxy = factory.CreateChannel(); 

     Console.WriteLine(proxy.Echo("This won't throw")); 

     try 
     { 
      Console.WriteLine(proxy.Echo("throw")); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Exception: {0}", e); 
     } 

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

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