1

このアプリケーションには、かなり単純なログフックのセット(MVCおよびAPIコントローラーのIExceptionFiltersとApplication_Error()の追加のキャッチオール)がありますが、それらのいずれもトリガーしないエラーのカテゴリ全体があります。WebAPI自体の内部から、または内部で使用されるもの(依存関係リゾルバーによって作成されるクラスの型初期化子など)から例外がスローされた場合、取得するのは500応答がクライアントに送信されることだけです。

エラーの詳細をキャプチャするために私が見つけた唯一の方法は、HttpConfiguration.IncludeErrorDetailPolicyを使用して、エラーの詳細を出力するようにアプリケーションを構成することです-ただし、エラーの詳細を世界中にブロードキャストすることは悪い習慣です。これを完全にオフにするか、条件付き(たとえば、ローカルのみ)に設定します。ただし、これは、アプリケーションが実行されているサーバーにリモートで移動し、応答を検査できるツール(IEやGoogleなど)を使用してAPIをローカルで呼び出すことを意味します。 Chrome)何が起こっているのかを理解するために。

私はここで同様の流れで別の質問を見ましたが(ここ)、提示された解決策(DelegatingHandlerを使用して応答を検査する)は私たちのニーズを満たしていないと思います。フックできるイベント、使用できる拡張ポイント、または発生した実際の例外をキャプチャするためのそのようなものは本当にありませんか?

(余談ですが、IncludeErrorDetailPolicyをAlwaysに変更し、他のスレッドで提示されたソリューションを使用して、MessageHandlerでエラーの詳細をキャプチャし、ログに記録して、クライアントに送信される応答から手動でスクラブすることができると思いますが、厄介なハックになります。)

考え?:/

4

2 に答える 2

1

マイクロソフト パートナー ネットワークにサポート リクエストを提出したところ、より適切な回答が得られました。

アイデアは、プラットフォームの既定の IHttpControllerActivator 実装を、既定のコントローラー作成動作を追加の必要な動作でラップする実装に置き換えることです。

私たちの場合、それは DefaultHttpControllerActivator の Create メソッドを try/catch/throw コンストラクトとログ サービスへの呼び出しでラップすることを意味します。これで 100% のカバレッジが得られるわけではありませんが、見逃している例外のほとんどはコントローラーの作成を扱っているため、大いに役立つはずです。

HttpControllerDispatcher 内で HandleException メソッドをフックできるようになりたいと思っていますが、これはプライベートでも静的でもあります。

于 2013-02-26T15:57:04.977 に答える
0

わかりました、あなたがやろうとしていることを理解しています。明確にしていただきありがとうございます。WebAPIには、エラー応答が必ずしも例外によって引き起こされるとは限らないモデルがあります。誰でも、実際に例外をスローすることなく、たとえば400でHttpResponseMessageを返すことができます。また、多くの場合、組み込みのフレームワークエラーは、例外をスローすることなく同じように機能します。

さて、あなたが提案したことは私にはうまく聞こえると思います。ErrorDetailPolicyをAlwaysに設定し、エラーをログに記録し、メッセージのみを含む別のHttpErrorを使用するメッセージハンドラーを実装できます。これがどのように見えるかです:

public class ErrorHandlingMessageHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
        HttpError error;
        if (response.TryGetContentValue(out error))
        {
            LogError(error)
            // Use an HttpError that doesn't leak internal information
            (response.Content as ObjectContent).Value = new HttpError(error.Message);
        }

        return response;
    }
}

既存のエラーをスクラブしていないことに注意してください。情報漏えいのリスクを減らすために、新しいものを作成しています。メッセージは常に安全に返送できる必要があります。これはモデル状態の返送には対応していませんが、必要に応じていつでも新しいエラーにコピーできます。

これについての考え方の1つは、ローカルクライアントに送信した応答を記録し、エラーの詳細を含まない安全なメッセージをリモートクライアントに送信できることです。

于 2013-01-18T20:25:41.917 に答える