私は長年、通常の ASP.NET Web API を使用してきましたが、新しい REST API プロジェクトに ASP.NET Core を使用しています。ASP.NET Core Web API で例外を処理する良い方法が見つかりません。例外処理フィルター/属性を実装しようとしました。
public class ErrorHandlingFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
HandleExceptionAsync(context);
context.ExceptionHandled = true;
}
private static void HandleExceptionAsync(ExceptionContext context)
{
var exception = context.Exception;
if (exception is MyNotFoundException)
SetExceptionResult(context, exception, HttpStatusCode.NotFound);
else if (exception is MyUnauthorizedException)
SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
else if (exception is MyException)
SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
else
SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
}
private static void SetExceptionResult(
ExceptionContext context,
Exception exception,
HttpStatusCode code)
{
context.Result = new JsonResult(new ApiResponse(exception))
{
StatusCode = (int)code
};
}
}
そして、これが私のスタートアップ フィルターの登録です。
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizationFilter());
options.Filters.Add(new ErrorHandlingFilter());
});
私が抱えていた問題は、 で例外が発生したときに、AuthorizationFilter
によって処理されないことですErrorHandlingFilter
。古い ASP.NET Web API と同じように、そこで例外がキャッチされると思っていました。
では、すべてのアプリケーション例外とアクション フィルターからの例外をどのようにキャッチすればよいのでしょうか?
ベストアンサー1
グローバル例外ハンドラ。最新の ASP.NET 8+
インターフェースを実装する例外ハンドラコンストラクターにロガーやその他の依存関係を挿入できます。
using Microsoft.AspNetCore.Diagnostics;
class MyExceptionHandler : IExceptionHandler
{
public async ValueTask<bool> TryHandleAsync(
HttpContext context,
Exception exception,
CancellationToken cancellation)
{
// Your response object
var error = new { message = exception.Message };
await context.Response.WriteAsJsonAsync(error, cancellation);
return true;
}
}
IExceptionHandler の実装が完了したら、このミドルウェアを登録するだけです。
builder.Services.AddExceptionHandler<MyExceptionHandler>();
app.UseExceptionHandler();
- IExceptionHandler 実装を複数追加することができ、登録順に呼び出されます。
- 例外が処理された場合は
true
から戻り、そうでない場合は を返し、次のハンドラーに渡されます。TryHandleAsync
false