2012-07-09 95 views
2

我的應用程序使用WCF調用Web服務。呼叫失敗有多種原因:在客戶端上記錄WCF錯誤

  • 故障
  • 超時
  • 連接丟失
  • ...

我要記錄所有的這些錯誤。與其將每個調用包裝在try-catch中,我都希望在一個地方爲整個應用程序中的所有Web服務調用執行此操作。

不幸的是,IClientMessageInspector不會因超時和連接失敗而被調用。 是否有可用於集中注意所有異常的WCF可擴展性?

請注意,我不只是想將錯誤記錄爲像WCF Tracing這樣的文本。我想記錄:

  • 服務名稱
  • 方法名
  • 時間
  • Exception.ToString()

我願意接受的解決辦法。

+0

你能提供您的通話之一的代碼示例的例子嗎?您目前是否正在創建,調用和處理每個電話的服務? – 2012-07-10 16:38:02

+0

@JTorres,我實例化服務代理每個「工作單元」一次,每個實例有1-10個調用。這意味着我不能重複使用這個地方來添加異常處理程序。 – usr 2012-07-10 16:52:06

+0

我相信我明白你在說什麼(創建一個服務引用,在上述服務上調用1到10個方法,銷燬引用)。你試圖做的是在這些方面添加一些形式的錯誤處理,而不用實際寫代碼中的錯誤處理,因爲(1)使代碼看起來很難看,(2)很多重新編碼需要做。不幸的是,我相信你很困難。我能想到的最接近「擴展」解決方案的方法是使用PostSharp之類的AOP實用程序,並使用適當的方面修飾您的調用。 @Trey Combs的解決方案可以改善設計。 – 2012-07-10 17:05:10

回答

1

我沒有意識到可擴展性,但我可以提供我們已經使用的解決方法。基本上,我們創建了一個所有服務調用都通過的「代理」。以下是代理及其使用示例。

/// <summary> 
/// Proxy for executing generic service methods 
/// </summary> 
public class ServiceProxy 
{ 
    /// <summary> 
    /// Execute service method and get return value 
    /// </summary> 
    /// <typeparam name="C">Type of service</typeparam> 
    /// <typeparam name="T">Type of return value</typeparam> 
    /// <param name="action">Delegate for implementing the service method</param> 
    /// <returns>Object of type T</returns> 
    public static T Execute<C, T>(Func<C, T> action) where C : class, ICommunicationObject, new() 
    { 
     C svc = null; 

     T result = default(T); 

     try 
     { 
      svc = new C(); 

      result = action.Invoke(svc); 

      svc.Close(); 
     } 
     catch (FaultException ex) 
     { 
      // Logging goes here 
      // Service Name: svc.GetType().Name 
      // Method Name: action.Method.Name 
      // Duration: You could note the time before/after the service call and calculate the difference 
      // Exception: ex.Reason.ToString() 

      if (svc != null) 
      { 
       svc.Abort(); 
      } 

      throw; 
     } 
     catch (Exception ex) 
     { 
      // Logging goes here 

      if (svc != null) 
      { 
       svc.Abort(); 
      } 

      throw; 
     } 

     return result; 
    } 
} 

而且其採用的例子:

var result = ServiceProxy.Execute<MyServiceClient, MyReturnType> 
(
    svc => svc.GetSomething(someId) 
); 
+0

該解決方案可以工作,但我不喜歡在整個應用程序中更改所有大約100個服務調用...並且我不想重新測試所有這些服務調用。我真的尋求某種中央解決方案。 – usr 2012-07-10 16:23:40

+1

如果你開始使用它,這將是一個很好的中央解決方案。它提供了相當強大的靈活性,但是現在可能不太可行,因爲現在你已經處於開發的前沿了。話雖如此,除了我不知道的奇蹟般的處理者/行爲,我不相信任何解決方案在這一點上都是無痛苦的。 – 2012-07-10 17:08:44