asp.netコアカスタム例外処理ミドルウェア
イントロ
asp.netコアで処理するグローバル例外は、それが私たちのニーズを満たすために、時にはことはできません、あなたは扱わ独自のミドルウェアが必要になる場合があり、最近問題に遭遇した、いくつかの例外はありますが、エラーを記録したくない、キーがありますユーザの要求にキャンセルTaskCanceledException
とOperationCanceledException
異常。歩哨に私ERRORレベルのログ出力は、歩哨例外が自動的に電子メールのアラートが送信されますので、いくつかの不要なミスならば、自然にエラーを記録する必要はありませんし、代わりに、ミドルウェア独自の例外処理を扱うカスタム例外をしたいです例外は、asp.netコアに直接例外処理を処理していません。
リクエストのキャンセル
異常なまでにキャンセル要求:
導入asp.netのコアHttpContext.RequestAborted
ユーザーを監視するためには、あなたが使用することができます(毎回トリガーは、100%のトリガがどのように把握ではないではない、ダウン実際の試験)の要求をキャンセルしHttpContext.RequestAborted
、ユーザが要求処理ロジックは、背景を中断キャンセルしたときに、不要なビジネス・プロセスを避けるため、以下の使用例を示し、サンプルソースコード
、より詳細な情報を見つけることができバイロンのこの割り込み要求が出て見つけるために
[HttpGet]
public async Task<IActionResult> GetAsync(string keyword, int pageNumber = 1, int pageSize = 10)
{
Expression<Func<Notice, bool>> predict = n => true;
if (!string.IsNullOrWhiteSpace(keyword))
{
predict = predict.And(n => n.NoticeTitle.Contains(keyword));
}
var result = await _repository.GetPagedListResultAsync(x => new
{
x.NoticeTitle,
x.NoticeVisitCount,
x.NoticeCustomPath,
x.NoticePublisher,
x.NoticePublishTime,
x.NoticeImagePath
}, queryBuilder => queryBuilder
.WithPredict(predict)
.WithOrderBy(q => q.OrderByDescending(_ => _.NoticePublishTime))
, pageNumber, pageSize, HttpContext.RequestAborted); // 直接使用 HttpContext.RequestAborted
return Ok(result);
}
// 在 Action 方法中声明 CancellationToken,asp.net core 会自动将 `HttpContext.RequestAborted` 绑定到 CancellationToken 对象
[HttpGet]
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
{
var result = await _repository.GetResultAsync(p => new
{
p.PlaceName,
p.PlaceIndex,
p.PlaceId,
p.MaxReservationPeriodNum
}, builder => builder
.WithPredict(x => x.IsActive)
.WithOrderBy(x => x.OrderBy(_ => _.PlaceIndex).ThenBy(_ => _.UpdateTime)), cancellationToken);
return Ok(result);
}
例外処理ミドルウェア
例外処理ミドルウェア出典:
public class CustomExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly CustomExceptionHandlerOptions _options;
public CustomExceptionHandlerMiddleware(RequestDelegate next, IOptions<CustomExceptionHandlerOptions> options)
{
_next = next;
_options = options.Value;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (System.Exception ex)
{
var logger = context.RequestServices.GetRequiredService<ILoggerFactory>()
.CreateLogger<CustomExceptionHandlerMiddleware>();
if (context.RequestAborted.IsCancellationRequested && (ex is TaskCanceledException || ex is OperationCanceledException))
{
_options.OnRequestAborted?.Invoke(context, logger);
}
else
{
_options.OnException?.Invoke(context, logger, ex);
}
}
}
}
public class CustomExceptionHandlerOptions
{
public Func<HttpContext, ILogger, Exception, Task> OnException { get; set; } =
async (context, logger, exception) => logger.LogError(exception, $"Request exception, requestId: {context.TraceIdentifier}");
public Func<HttpContext, ILogger, Task> OnRequestAborted { get; set; } =
async (context, logger) => logger.LogInformation($"Request aborted, requestId: {context.TraceIdentifier}");
}
あなたが設定することができCustomExceptionHandlerOptions
、カスタムの例外処理ロジックを実装するために、エラー・ログを、レコードレベルのログ情報をキャンセルするデフォルトの要求は、他の例外はエラーのレベルを記録します
あなたが遭遇したときは異常何もしないの次の例要求のキャンセルにより構成することができます
service.Config(options=>
{
options.OnRequestAborted = (context, logger) => Task.CompletedTask;
});