2012-04-23 32 views
11

まず、私が作成し、ExceptionFilterAttributeを継承する例外フィルタを使用しています。これは、私たちのIDフィルタの直後にアプリケーションの起動時にconfigに登録され、API内のどこかでエラーが発生した場合、期待どおりに動作します。例外処理ASP.NET MVC Web API

私は、APIに到達する前に発生したエラーを処理する方法を探しています。

推論: YSODおよび/またはIIS HTMLエラーを返すことは決してありません。私たちは常にロギングを正しく処理し、JSONレスポンスをユーザに返すことができるようにカスタム例外フィルタ/ハンドラを起動したいと考えています。

今のところ、Fiddlerを使用してリクエストを作成すると、w3wp.exeプロセスにアタッチして、要求がglobal.asaxのApplication_BeginRequestメソッドにヒットすることがあります。その後、500応答を返します。それは、例外を伴ってコード内で壊れたり、その後に私のブレークポイントのどれにも当たったりしません。それはIISエラーを返すようです。私たちはこれが起こることは決してありません。これらの「低レベル」の例外をすべてキャッチしてログに記録し、ユーザーに意味のあるものを返す機能が必要です。

ASP.NET MVC Web APIコードに当てはまるようなエラーが以前にあったのですか?

+0

これは何とか間違っています。どこかの図書館に例外を投げていますか?コントローラーで例外をキャッチして、自分が選択したエラービューを返すのはなぜですか? –

+1

これはASP.NET MVC Web APIを使用しているため、コントローラからビューを返すことはありません。 JSON/XMLレスポンスを返します。私はまた、コントローラに到達する前に例外を処理する方法が必要であると私の質問で言及します。今は、コントローラーの中にいたらどこにでも例外をキャッチするExceptionFilterがありますので、すべてのアクションでtry/catchを行う必要はありません。 – phreak3eb

+0

私はあなたの質問を完全に理解しているとは思わない。どんな種類のエラーを正確に捕まえようとしていますか? – cecilphillip

答えて

4

私はDarinの答えが好きですが、ASP.NET MVC Web APIフレームワークは内部的に例外を抑制/処理していて、Global.asaxのApplication_Errorメソッドにヒットするために再スローしていないため、このケースではうまくいきません。私たちのソリューションはこれです。

私はそうのようなカスタムDelegatingHandler作成することになった:

public class PrincipalHandler : DelegatingHandler 
{ 
    protected const string PrincipalKey = "MS_UserPrincipal"; 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     setAnonymousPrincipal(); 

     request = InitializeIdentity(request); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(r => 
           { 
            // inspect result for status code and handle accordingly 
            return r.Result; 
           }); 
    } 
} 

を私はヒットする最初/最後のハンドラであることを確認するためにHttpConfigurationにそれを挿入します。ハンドラがWeb APIで動作する方法は、階層的な方法で行われます。リクエストごとにヒットする最初のハンドラは、レスポンスでヒットする最後のハンドラになります。少なくともこれは私の理解であり、私が間違っていると誰かが私を修正する気がします。

public static void ConfigureApis(HttpConfiguration config) 
{ 
    config.MessageHandlers.Insert(0, new PrincipalHandler()); 
} 

このアプローチを使用することで、Web APIとコントローラからの応答に戻るすべての結果を検査できるようになりました。これにより、期待どおりに返されなかった結果として発生する必要のあるログを処理することができます。 HTTPレスポンスの内容を変更して、特定のHTTPステータスコードが表示された場合にIISがデフォルトのHTMLエラーページを挿入しないようにすることもできます。

私がこれを持っている唯一の問題は、Web APIの今後のリリースで変更することを願っています。彼らは例外をbase.SendAsyncから返されたタスクに戻して送信していないということです)。だから、私たちがやらなければならない唯一の情報は、HTTPのステータスコードであり、消費者に合理的または可能性のある回答を与えるために最善を尽くしてください。

+0

'config.MessageHandlers.Insert()'の呼び出しを結ぶためのドキュメントを探している人は、[WebAPIのドキュメント]で入手できます(http://www.asp.net/web-api/overview/working-with -http/http-message-handlers)を使用します。 –

+1

完全な例外情報があるWeb APIでグローバルエラーハンドラが必要な場合は、http://aspnetwebstack.codeplex.com/workitem/1001で投票してください。 –

+0

これは便利なバリエーションのようです。http:// blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro