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
これらは、webapi自体のGlobalConfigurationでオンにする必要があることがわかりました。
1: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
2: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
3: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
実際にサーバーが表示する詳細の量を決定します。デフォルトはLocalOnlyです。
私たちのロギングメソッドはローカルとは見なされません。これは、実際にはAPI自体に組み込まれているのではなく、複数のAPI間の共有DLLにあるためです。
thisの記事が非常に参考になりました。
私はこれを使いました:
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy
= IncludeErrorDetailPolicy.Always;
aPIのグローバルで、それは成功しています。