我们提供安全,免费的手游软件下载!
在ASP.NET Core中,可以通过中间件(Middleware)实现全局的异常处理。内置的异常处理中间件UseExceptionHandler是一个常用的选项。
使用内置的异常处理中间件UseExceptionHandler:
app.UseExceptionHandler(appError =>
{
appError.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get();
if (contextFeature != null)
{
logger.LogError($"Something went wrong: {contextFeature.Error}");
await context.Response.WriteAsync(new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error."
}.ToString());
}
});
});
另一种方法是自定义一个完全自定义的中间件:
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILoggerManager _logger;
public ExceptionMiddleware(RequestDelegate next, ILoggerManager logger)
{
_logger = logger;
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
_logger.LogError($"Something went wrong: {ex}");
await HandleExceptionAsync(httpContext, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
await context.Response.WriteAsync(new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error from the custom middleware."
}.ToString());
}
}
除了中间件,还可以使用过滤器(Filter)来实现全局异常处理,即IExceptionFilter。这些方法都能方便地实现自定义的全局异常处理。
在.NET 8.0中,微软引入了IExceptionHandler,这也可以实现相同的功能。根据官方的异常处理文档,IExceptionHandler似乎已经成为最推荐的异常处理方法。
在微软新开的项目中,IExceptionHandler正被广泛使用,比如Semantic Kernel。
下面是官方文档给出的一个简单实现:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
public class CustomExceptionHandler : IExceptionHandler
{
private readonly ILogger logger;
public CustomExceptionHandler(ILogger logger)
{
this.logger = logger;
}
public ValueTask TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
var exceptionMessage = exception.Message;
logger.LogError(
"Error Message: {exceptionMessage}, Time of occurrence {time}",
exceptionMessage, DateTime.UtcNow);
// Return false to continue with the default behavior
// - or - return true to signal that this exception is handled
return ValueTask.FromResult(false);
}
}
}
使用也很简单:
builder.Services.AddExceptionHandler();
然而,如果按照文档实现完之后,自定义异常处理并不会生效,必须添加一个空的lambda给UseExceptionHandler、AddExceptionHandler才会生效:
app.UseExceptionHandler(o => { });
为什么会这样?有人发现微软尝试修复这个问题,但是改动有breaking change给拒绝了,加上有上面提到的workaround,就一直搁置了。
虽然这种方法依然可用,但是看着难受。开头介绍了,UseExceptionHandler是启用内置的异常处理中间件的方法,而AddExceptionHandler是用来注册.NET 8.0新引入的IExceptionHandler。这个workaround有点一言难尽,欢迎踊跃提交PR去fix,先到先得☺
相关资讯
热门资讯