2016-05-03 4 views
0

は、ここで私はこれまで試してみましたものです:ASP.NETアプリケーション内で例外をシリアル化するにはどうすればよいですか?

{"message":"An error has occurred.","exceptionMessage":"A circular reference was detected while serializing an object of type 'Entities.Models.Core.Word'.","exceptionType":"System.InvalidOperationException","stackTrace":" at .....

は、私がex.MessageとのInnerExceptionを返すようにしたい:私はシリアル化しようとすると

public async Task<IHttpActionResult> Post([FromBody]Word word) 
    { 
     try 
     { 
      db.Words.Add(word); 

      await db.SaveChangesAsync(User, DateTime.UtcNow); 
      return Ok(word); 
     } 
     catch (Exception ex) 
     { 
      return BadRequest(new JavaScriptSerializer().Serialize(ex)); 
     } 
    } 

、私は次のエラーを取得します。しかし、1つ以上の内部例外が存在するかどうかはわかりません。

+0

のようなものを使用して、内部例外を反復処理することができ、エラーがで発生しました「を返すOK(単語);」ライン? –

+0

この特定のケースでは、重複している主キーを挿入していましたが、内部例外がこれを教えてくれました。私の問題は、これを報告してフロントエンドに返信する方法です。 –

+0

あなたはajaxコールでエラー機能があると思いますか?そこにレスポンスを取得し、response.exceptionMessageを実行してエラーを取得します。 –

答えて

1

を必要とするものONY以外のすべてをシリアル化するためではないだろう

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

を追加します私のWeb APIプロジェクト。私は引数としてスローされた例外を渡し、その後HttpResponseExceptionを返してスローします。

スローされた例外は、自動的にHTTP動詞関数の戻り値の型にシリアライズされます。私の例では、.Net型を汎用オブジェクトにシリアライズするので、Taskを返します。

あなたは私の例を見れば、あなたは、私はタスクに設定され、その戻り値の型を持つメソッドと呼ばれる取得を持って表示されますの下に。この方法は、それがタスクの戻り型をシリアル化します返す場合、フロントエンドアプリケーションは、「アプリケーション/ JSON」に設定AcceptヘッダーとHTTPのGET(あなたの場合にPOST)を実行する場合、オブジェクト・タイプは、JSONにシリアライズしますjsonにこれは、text/xmlのAccept型に対しても機能します。

私はあなたのヘルパーメソッド内の特定のデータをフィルタリングすることをお勧めしたいです。おそらくあなたのAPIを消費している人々が完全なスタックトレースなどを得ることを望まないでしょうが、明らかにこれはあなたの必要条件になります。ヘルパーメソッドで

public async Task<Object> Get() 
{ 
    object result = null; 
    try 
    { 
     result = await methodThatThrowsException(); 
    } 
    catch (Exception ex) 
    { 
     throw CreateHttpResponseException(ex); 
    } 
     return result; 
} 

ヘルパー・メソッド

private HttpResponseException CreateHttpResponseException(Exception ex) 
{ 
    HttpResponseMessage message; 
    if (ex.GetType() == typeof(FaultException<LoginFault>)) 
    { 
     message = new HttpResponseMessage(HttpStatusCode.Forbidden); 
    } 
    else 
    { 
     message = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 

    message.Content = new StringContent(ex.Message); 
    return new HttpResponseException(message); 
} 

、あなたのフロントエンドに表示するものを構築するためのStringBuilderを使用しています。連結し、あなたが必要とするあなたのエラーメッセージをフォーマットしてからごMessageResponseMessage.Contentフィールドに文字列値を割り当てます。

例外InnerExceptionを反復処理し、nullかどうかを確認し、必要に応じて例外メッセージなどを連結する必要があります。

あなたは

StringBuilder exceptionMessage = new StringBuilder(); 
Exception inner = ex.InnerException; 
while (inner != null) 
{ 
    exceptionMessage.Append(inner.Message) 
        .Append(Environment.NewLine); 
    inner = inner.InnerException; 
} 
1

あなたからexpcetion問題は、おそらく何か他のものにrefferenceを持っていて、遅延ロードを使用しているEntities.Models.Core.Wordのオブジェクトを保存しようと、次のされています。したがって、シリアライザがオブジェクトを直列化しようとすると失敗します。 これを修正する方法はほとんどありません。 Application_Start中のglobal.asaxで

2番目のオプションを使用すると、私は通常で例外処理を扱うヘルパー関数を使用し

return BadRequest(new JavaScriptSerializer().Serialize(new 
      { 
       ex.Message, 
       ex.StackTrace 
      })); 
関連する問題