2017-05-29 12 views
1

私はWebAPIプロジェクトを持っており、try/catchからキャッチするexceptionexceptionfiltersに移動しています。以前私がtry/catchブロックを使用したとき、私はSQLコマンドオブジェクトにアクセスして、SQLコマンドテキストをデータベースに記録することができました。今度は例外フィルタに移りましたので、もはやSQLコマンドオブジェクトにアクセスすることはできません。私が後にしているのは、最後に実行されたコマンドSQLを例外フィルタに渡して、まだログできるようにする方法です。ExceptionFilterに値を渡します

前のコード(のtry/catchブロック)

public HttpResponseMessage API([FromBody] int roomID) 
{ 
    HttpResponseMessage msg = null; 
    SqlCommand comm = Common.Shared.ConnectDB(); 

    try 
    { 
     List<Models.room> room = room(comm, roomID); 
     msg = Request.CreateResponse(HttpStatusCode.OK, room); 
    } 
    catch (CustomException ex) 
    { 
     msg = Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); 
    } 
    catch (Exception ex) 
    { 
     comm.Parameters.Clear(); 
     var sourceFunction = "rooms"; 
     var returnException = Common.Logging.CreateLog(ex, comm, sourceFunction); 
     msg = Request.CreateResponse(HttpStatusCode.InternalServerError, returnException); 
    } 
    finally 
    { 
     comm.Connection.Close(); 
    } 
    return msg; 
} 

例外フィルタコード

public class InternalServerErrorFilter : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext context) 
    { 
     Log.Error(context.Exception, "Exception Information"); 

     context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 
} 

コントローラの例外フィルタ

[InternalServerErrorFilter] 
[HttpPost] 
public HttpResponseMessage API([FromBody] int roomID) 
{ 
    HttpResponseMessage msg = null; 
    SqlCommand comm = Common.Shared.ConnectDB(); 

    try 
    { 
     List<Models.room> room = room(comm, roomID); 
     msg = Request.CreateResponse(HttpStatusCode.OK, room); 
    } 
    finally 
    { 
     comm.Connection.Close(); 
    } 
    return msg; 
} 

答えて

1

あなたはそのシナリオを扱うことができるいくつかの方法があります。

ExceptionタイプをチェックしてSqlException(チェックdocumentation)のようなより具体的な例外にキャストします。 SqlExceptionの中にその例外の理由を見つけることができます。

public class InternalServerErrorFilter : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext context) 
    { 
     if (context.Exception is SqlException) 
     { 
      var sqlException = (SqlException)context.Exception; 
      //Do your logging... 
     } 
     context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 
} 

それとも、あなたはさらに、ロギングのためのあなたのSqlCommandを渡しますするカスタムSQL例外を作成することができます。ただし、厳密に型指定されたアクセスを取得するには、上記のようにタイプをチェックする必要があります。

public class CustomSqlException : Exception 
{ 
    public SqlCommand ExecutedCommand { get; } 

    public CustomException(SqlCommand executedCommand) 
     : base("Custom Message") 
    { 
     ExecutedCommand = executedCommand; 
    } 
} 

public class InternalServerErrorFilter : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext context) 
    { 
     if (context.Exception is CustomSqlException) 
     { 
      var sqlException = (CustomSqlException)context.Exception; 
      var command = sqlException.ExecutedCommand; 
      //Do your logging... 
     } 
     context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 
} 

用法:

[InternalServerErrorFilter] 
    [HttpPost] 
    public HttpResponseMessage API([FromBody] int roomID) 
    { 
     HttpResponseMessage msg = null; 
     SqlCommand comm = Common.Shared.ConnectDB(); 

     try 
     { 
      List<Models.room> room = room(comm, roomID); 
      msg = Request.CreateResponse(HttpStatusCode.OK, room); 
     } 
     catch (SqlException ex) 
     { 
      throw new CustomSqlException(comm); 
     } 
     finally 
     { 
      comm.Connection.Close(); 
     } 
     return msg; 
    } 

私はSqlExceptionは、SQLサーバー上のSQLコマンドの実行中に発生しましたエラーに関するすべての必要な情報を持っている必要がありますので、あなたが、最初のアプローチを使用することをお勧め。それに加えて、新しい例外が投げられるため、スタックトレースを失うことはありません。

2番目の解決方法を使用する場合は、CustomSqlExceptionの例外として例外を渡してスタックトレースを失う問題を回避できます。

+0

これはSQLの例外に対して機能します。しかし、私はまた、SQL例外をスローしないので、私はデータリーダなどで使用されたコマンド文字列を取得しません – Nathan

+0

他の例外のためのSQLコマンドをつかむことを望んでいた@ネイサンあなたは2番目のオプションで行くことができます。ただし、データリーダーによって手動で発生した例外を手動で処理する必要があります。 'SqlException'をキャッチする必要はなく、' Exception'をキャッチすることができます。 –

関連する問題