2011-01-19 11 views
14

このような状況の処理方法は混乱しています。AjaxリクエストのAsp.Net MVCアクションで未処理の例外(エラー500の応答)を処理する最良の方法は何ですか?

通常、未処理のASP.Net例外が発生した場合、サーバーは、デフォルトのAsp.NetエラーハンドラまたはカスタムエラーハンドラのいずれかのHTMLメッセージを返します。どちらの場合でも、HTMLが返送されています(通常はページを使いやすくすることをお勧めします)。

しかし、Ajax呼び出しでJSONを返すと予想されるAsp.net MVCコントローラのアクションで未処理の例外が発生しています。 javascriptが返されたページ(意図したJSONの代わりにHTML)を読み込むと、レスポンスをJSONに変換できないためクラッシュします(今はExtJSを使用しています)。例外が発生したときにJsonを返して、エラーが発生したことをユーザーに通知できるようにします。

私は考えることができる唯一のソリューションは、JSONを返すすべてのアクションで次の操作を実行することです:それは私が明らかに悪いである(すべての例外をキャッチする必要があるため、私はその方法好きではない

try { .... } 
catch (Exception ex) 
{ 
    return Json(new { success = false, msg = ex.Message }); 
} 

理由)、同じ例外処理コードを使用して、すべてのJsonResultアクションを処理する必要があります(後で変更するのが難しくなります)。

Jsonを返すアクションメソッドでのみ、より適切なエラー結果を返すためのより良い方法がありますが、Ajax以外のWebリクエストに対しては通常のエラーページをユーザーフレンドリーに保ちますか?

答えて

12

ここで私は、この問題を解決する方法は次のとおりです。

public class HandleJsonError : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext exceptionContext) 
    { 
     if (!exceptionContext.HttpContext.Request.IsAjaxRequest() || exceptionContext.Exception == null) return; 

     exceptionContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError; 
     exceptionContext.Result = new JsonResult 
            { 
             Data = new 
                { 
                 exceptionContext.Exception.Message, 
                 exceptionContext.Exception.StackTrace 
                } 
            }; 

     exceptionContext.ExceptionHandled = true; 
    } 
} 
+6

代わりにHandleErrorAttributeから継承し、OnExceptionを上書きすることができます。このようにして、フィルタはすべての要求ではなく、例外が発生した場合にのみ起動します。 –

+0

アクションフィルタが役立つようです。これはコードによる回答としてマークしてください! – KallDrexx

+0

@ The Flower Guy:ああ、そうだよ。私はチャンスを得るときにショットを与えるでしょう。ありがとう! – adamjford

1

カスタムActionFilterを使用して、その中にjavascriptリクエストの場合は、HTMLページではなくJSONオブジェクトとしてレスポンスをフォーマットできます。 HandleErrorは、基底クラスを拡張するのに適した場所です。

アクチオフィルターを使用したくない場合は、コントローラーのOnExceptionをオーバーライドし、exceptionContext.Resultをエラーを示す新しいJsonResultに設定することもできます。

3

あなたはコントローラにonExceptionをオーバーライドして、あなたがコードを呼び出すあなたのJavaScriptで処理する必要があるでしょうJSONエラーレスポンスを返すために、いくつかのロジックに置くことができます:

protected override void OnException(ExceptionContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      filterContext.Result = Json("..."); 
     } 
     else 
     { 
      base.OnException(filterContext); 
     } 
    } 

「正しく」実行したい場合は、ほとんど同じコードでアクションフィルタを作成し、すべてのコントローラに適用できます。 MVC3を使用している場合は、すべてのコントローラーに適用されるようにグローバルフィルターにすることができます。

関連する問題