2013-04-18 14 views
9

サービスクライアントがすべてWebServiceExceptionをスローしたいと思っています。今すぐこれを行うには良い方法がありますか?ServiceClientBaseの例外ハンドラ

たとえば、私はWindowsフォームアプリケーションの周りに単一のServiceClientBaseを渡しています。 httpヘッダーのapiキーをサーバーに渡しています。 APIキーが有効でないリクエストについては、リクエストが不正であり、APIキーを設定する必要があることをユーザーに伝えるメッセージボックスを表示したいとします。しかし、私はどこにでもこのコードをしたくない。このような

try 
{ 
    _client.Get(new ReqDto()); 
} 
catch (WebServiceException ex) 
{ 
    if(ex.StatusCode == 401) 
     Util.ShowUnauthorizedMessageBox(); 
} 

何かがいいだろう:

_client.WebServiceExceptionHandler += TheHandler; 

私はにフックすることができますローカル応答フィルタがあります知っているが、私は、マテリアライズドWebServiceExceptionを必要とします。

私はServiceClientBase.csで何ができるかを見ていますが、何か助けていただければ幸いです。ありがとう。

答えて

2

APIの質問ではなく、設計上の質問としてこれをアプローチすると、答えはサービスクライアントをラップすることです。個人的には、同様のことをしているので、クライアントでサービスの例外を記録できます。

これは出発点のようになります。

public class MyServiceClient : IDisposable 
{ 
    public ServiceClientBase ServiceClient { get; set; } 

    string _serviceUri; 
    public string ServiceUri 
    { 
     get { return _serviceUri; } 
     set { _serviceUri = value; ServiceUriChanged(); } 
    } 

    public MyServiceClient() 
    { 
     ServiceUri = "http://127.0.0.1:8080"; 
    } 

    public void Dispose() 
    { 
     ServiceClient.Dispose(); 
    } 

    public TResponse Get<TResponse>(IReturn<TResponse> request) 
    { 
     try 
     { 
      return ServiceClient.Get(request); 
     } 
     catch (WebServiceException ex) 
     { 
      if(ex.StatusCode == 401) 
       Util.ShowUnauthorizedMessageBox(); 
     } 
    } 

    void ServiceUriChanged() 
    { 
     if (ServiceClient != null) 
      ServiceClient.Dispose(); 
     ServiceClient = new JsonServiceClient(ServiceUri); 
    } 
} 

時間が経つにつれて、あなたは、このようなすべての要求[デバッグコンソールへ] &応答をログに記録する、ローカルキャッシュ機能を追加するなど、間接のこの追加のレベルに他の利点を、見つけることがあります。そして、すべてのクライアントコードで使用されると、維持するのがかなり安いです。

APIに関しては、あなたが望むものは提供していないと思います。個人的には、私はそのままで満足しています(特にIReturn<T>インターフェイスは、あなたが望むような機能を統合する際に役立ちます)。しかし、あなたがそれに満足していなければ、あなたはそれを改善するためにDemisというダイアログから離れて1つのプルリクエストです。 ( - =

1

これはちょっと遅かったですが、私は同じことをしていましたので、ソースを掘り起こすようになりました。実際には簡単な修正があります。HandleResponseExceptionメソッドをあなたのServiceClient 。コメントから直接使用した:

 /// <summary> 
     /// Called by Send method if an exception occurs, for instance a System.Net.WebException because the server 
     /// returned an HTTP error code. Override if you want to handle specific exceptions or always want to parse the 
     /// response to a custom ErrorResponse DTO type instead of ServiceStack's ErrorResponse class. In case ex is a 
     /// <c>System.Net.WebException</c>, do not use 
     /// <c>createWebRequest</c>/<c>getResponse</c>/<c>HandleResponse&lt;TResponse&gt;</c> to parse the response 
     /// because that will result in the same exception again. Use 
     /// <c>ThrowWebServiceException&lt;YourErrorResponseType&gt;</c> to parse the response and to throw a 
     /// <c>WebServiceException</c> containing the parsed DTO. Then override Send to handle that exception. 
     /// </summary> 

私は個人的にJsonServiceClient

protected override bool HandleResponseException<TResponse>(Exception ex, object request, string requestUri, Func<System.Net.WebRequest> createWebRequest, Func<System.Net.WebRequest, System.Net.WebResponse> getResponse, out TResponse response) 
    { 
     Boolean handled; 
     response = default(TResponse); 
     try 
     { 
      handled = base.HandleResponseException(ex, request, requestUri, createWebRequest, getResponse, out response); 
     } 
     catch (WebServiceException webServiceException) 
     { 
      if(webServiceException.StatusCode > 0) 
       throw new HttpException(webServiceException.StatusCode, webServiceException.ErrorMessage); 
      throw; 
     } 
     return handled; 
    } 
の私のオーバーライドで、次のようなことをやっています
関連する問題