web-dev-qa-db-ja.com

サーバーでwebapiを実行する場合とローカルで実行する場合にHTTPError例外メッセージが表示されない

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

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

しかし、私の問題は、上記のように内部サーバーエラー500を引き起こしたときに、webapiを実行しているローカルマシンで、「複数のアクションが一致するものが見つかりました内部サーバーエラーの理由として、「リクエスト」と明記されています。しかし、この正確なコードをサーバーにデプロイし、そこから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
29
cookiekitty

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

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

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

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

thisの記事が非常に参考になりました。

59
cookiekitty

私はこれを使いました:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy
          = IncludeErrorDetailPolicy.Always; 

aPIのグローバルで、それは成功しています。

4
ptvce