33

IIS7.5 サーバーで実行される webapi があります。3 つのコントローラーがあり、3 つすべてを使用して、アプリケーション内の呼び出しから webapi にアクセスできます。

コントローラーの基本クラスが、関数を保護ではなくパブリックとして公開しているというエラーが発生しました。これにより、サーバーは内部サーバー エラー 500 をスローしました (「要求に一致する複数のアクションが見つかりました」という無効な例外がスローされたため)。webapi からログがトリガーされなかったため、これを掘り下げるのに時間がかかりました。ここでの議論から、発生していたエラーは、 Application_Error 関数がそれをキャッチしてログに記録する前に発生していたことを発見しました。そこで、以下のコードを webapi の global.asax に追加したところ、このようなエラーをログに記録できるようになりました。

しかし、私の問題は、上記とまったく同じように内部サーバー エラー 500 を発生させたときに、webapi を実行しているローカル マシンで、「一致する複数のアクションが見つかりました。 the request」が内部サーバー エラーの理由として綴られています。しかし、この正確なコードをサーバーにデプロイし、そこから webapi を使用すると、ログに「メッセージ」のみが表示されます。「エラーが発生しました」と表示され、「ExceptionMessage」は表示されません。 PerfView を使用してスローされます。サーバー ログを取得して、ローカル ログに表示される情報と同じ情報を表示できるようにする必要があるだけです。

public class ResponseExceptionTrapper : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        return base
            .SendAsync(request, cancellationToken)
            .ContinueWith(response =>
            {
                var result = response.Result;
                if (!result.IsSuccessStatusCode)
                {
                    var exceptionResult = string.Format(
                         "Response exception: \r\n Path({0}) \r\n Status({1}) \r\n",
                         request.RequestUri,
                         result.StatusCode);

                    if (result.Content != null)
                    {
                        var exceptionReadTask =
                               result.Content.ReadAsStringAsync();

                        exceptionReadTask.Wait();
                        exceptionResult += "Message:" +
                                          exceptionReadTask.Result;

                    }

                    // Do something appropriate with exceptionResult
                    exceptionResult.Log();
                }

                return result;
            }, cancellationToken);
    }
}

サーバーログの例:

Timestamp: 4/24/2014 12:24:40 PM
Message: Timestamp: 4/24/2014 4:24:40 PM
Message: Response exception: 
Path(http://webserver/CreditReporting/Api/RetrieveQueuedPullCreditReport) 
Status(InternalServerError) 
Message:{"Message":"An error has occurred."}

ローカル ログの例:

Timestamp: 4/24/2014 12:03:16 PM
Message: Timestamp: 4/24/2014 4:03:16 PM
Message: Response exception: 
 Path(http://localhost:XXXXX/Api/RetrieveQueuedPullCreditReport) 
 Status(InternalServerError)
 Message:
  {"Message":"An error has occurred.",
  "ExceptionMessage":"Multiple actions were found that match the request:
    \r\nSystem.Threading.Tasks.Task`1[
 Our.WebServices.CreditReporting.Contracts.RetrieveQueuedPullCreditReportResponse] Post
4

2 に答える 2

62

これらは、webapi 自体の GlobalConfiguration で有効にする必要があることがわかりました。

1: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
2: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
3: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;

サーバーは実際に表示する詳細を決定します。デフォルトは LocalOnly です。

私たちのロギング メソッドはローカルとは見なされません。これは、実際には API 自体に組み込まれておらず、複数の API 間で共有されている dll にあるためだと思います。

この記事はとても役に立ちました。

于 2014-04-29T20:27:46.147 に答える