2011-07-18 13 views
2

カスタムIErrorHandlerを使用してREST WCFサービスを使用しているため、サービスで未知の例外がすべて検出され、カスタムエラーメッセージ、適切なHttpステータスコード(500)エラー。IErrorHandlerを使用したREST WCFサービスはSerializationExceptionsをキャッチします

問題は、IErrorHandlerが自分のコードから発生した例外を捕捉するため、たとえば無効なJSONデータを持つサービスにPOSTを実行すると、SerializationExceptionが発生します。この例外はIERrorHandlerのためのものでなければ、ステータスコードBadRequest 400を持つWebFaultExceptionに変換されていました。他のすべての未知の例外と同様に扱います。

このような状況を処理する方法はありますか?IErrorHandlerでSerializationExceptionsをキャッチしてBadRequestを設定するだけですか?私のコードから抜粋せずにWCFスタックから他の例外を取り除くことができますか?

更新:は、私は同様の問題に遭遇したIErrorHandler.ProvideFault

public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     Guid loggingId = Guid.NewGuid(); 
     error.Data["ExceptionLoggingId"] = loggingId; 

     if (error is SecurityTokenException) 
     { 
      fault = Message.CreateMessage(version, string.Empty, String.Format("{0}. The error identifier is {1}", error.Message, loggingId), new DataContractJsonSerializer(typeof(string))); 
      fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json)); 

      webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.Unauthorized); 
     } 
     else 
     { 
      if (error is SerializationException) 
      { 
       // TODO: What if the SerializationException originates from within the service? 
       // SerializationException due to malformed JSON 
       return; 
      } 

      fault = Message.CreateMessage(version, string.Empty, String.Format("An unknown error has occurred. The error identifier is {0}", loggingId), new DataContractJsonSerializer(typeof(string))); 
      fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json)); 

      webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.InternalServerError); 
     } 
} 
+0

ProvideFaultにフォルトメッセージを割り当てないとどうなりますか? –

+0

それは期待どおりに動作します。クライアントはhttpステータスコード400を受け取ります。しかし、IErrorHandlerでSerializationExceptionsをチェックする必要があります。しかし、SerializationExceptionがWCFスタックからではなく私のサービスから来ている場合は、サーバーエラーです(いくつかのシリアル化は間違っています)。ステータスコード500を返したいと思いますか? – Joel

+0

私の意図を明確にするために私の実装を追加しました – Joel

答えて

1

の私の実装を追加しました。

私の解決策は、名前空間を使用して例外の原因を特定することでした。

if (!error.StackTrace.TrimStart().StartsWith("at " + this.GetType().Namespace.Split('.')[0])) 
    return; 

これは私の現在のプロジェクトで機能します。しかし、あなたのプロジェクトによっては、そうでないかもしれません...

+0

チップをありがとう!しかし、私は何か難しいコードをしたいと思います。現時点では、シリアライズ例外をキャッチして、それらを正しいステータスコードに変換しています – Joel

0

私は@RichardBlewettが正しいと思います。カスタム例外クラスを作成してそれをスローし、そのタイプをエラーハンドラでチェックしてから、標準のシリアライゼーション例外が正常に流れるようにします。それは私にとって最高のデザインパターンのようです。

その後、削除または変更すると、エラーハンドラコードがコンパイルされないか、VSを使用してタイプをリファクタリングするタイプセーフな例外が発生します。そのような名前空間をテストすることは、コンパイル時に直接型に結びついているわけではないので、おそらくそれほど巧妙ではありません。名前空間を変更すると、追跡が困難な問題に遭遇します。

関連する問題