龙空技术网

.Net 8 中错误处理的新方法

opendotnet 362

前言:

当前你们对“net发生了无法处理的异常”可能比较关怀,我们都想要分析一些“net发生了无法处理的异常”的相关文章。那么小编也在网上汇集了一些对于“net发生了无法处理的异常””的相关资讯,希望咱们能喜欢,我们快快来了解一下吧!


我们都在努力使应用程序平稳运行,您可能还记得,我之前讨论过完全最小化异常的策略。然而,即使是最健壮的代码也会遇到路上的颠簸。这就是异常处理的用武之地。

ASP.NET Core 提供了各种方法来管理这些意外情况。问题是,哪种方法最好?让我们探索您的选择,并找到最适合您应用的方案。

ASP.NET Core 中的异常处理

在 ASP.NET Core 中实现异常处理的首选方法是使用中间件。中间件充当中介,允许您在处理 HTTP 请求之前或之后拦截和注入自定义逻辑。这种灵活性使其成为集中处理异常的理想选择。

您可以通过在中间件组件中合并一个块来实现这一点。如果在请求处理过程中发生异常,块将捕获它。在这里,您可以选择记录错误以进行进一步分析,然后向客户端返回适当的 HTTP 错误响应。

ASP.NET Core 提供了三种创建中间件的主要方法:

Request Delegates: 这种方法涉及定义一个输入对象的函数。此函数表示中间件的核心逻辑,可以处理其范围内的异常。

By Convention: 此方法利用了基于约定的方法。您可以在中间件类中建立一个方法,负责处理请求并根据需要处理异常。

IMiddleware Interface: 这种方法在实现接口时提供了更大的控制。此接口规定了所需的方法,这些方法成为中间件逻辑和异常处理的入口点。IMiddleware

基于约定的方法要求您定义一种方法。

下面是按约定定义的示例:ExceptionHandleMiddleware

public class ExceptionHandleMiddleware

{

private readonly RequestDelegate _next;

private readonly ILogger<ExceptionHandlingMiddleware> _logger;

public ExceptionHandleMiddleware(

RequestDelegate next,

ILogger<ExceptionHandlingMiddleware> logger)

{

_next = next;

_logger = logger;

}

public async Task InvokeAsync(HttpContext context)

{

try

{

await _next(context);

}

catch (Exception exception)

{

_logger.LogError(

exception, "Exception: {Message}", exception.Message);

var problemDetails = new ProblemDetails

{

Status = StatusCodes.Status500InternalServerError,

Title = "Error"

};

context.Response.StatusCode =

StatusCodes.Status500InternalServerError;

await context.Response.WriteAsJsonAsync(problemDetails);

}

}

}

将捕获任何未处理的异常,并返回 Problem Details 响应。您可以决定要返回到多少信息。您还需要将此中间件添加到 ASP.NET Core 请求管道中:ExceptionHandleMiddleware

app.UseMiddleware<ExceptionHandleMiddleware>();

使用 IExceptionHandler 简化异常处理

ASP.NET Core 8 引入了接口,为异常管理带来了更简洁的方法。此接口充当处理应用程序中的异常的中心点。

内置的异常处理程序中间件依赖于 的实现来处理处理过程中发生的错误。此接口提供单一方法:

当出现异常时,该方法将接管。它的作用是确定它是否可以处理 ASP.NET Core 管道中的特定异常。如果它可以有效地解决问题,它将返回 。但是,如果异常超出了其能力范围,它将返回 。这允许您创建用于处理不同类型异常的自定义逻辑,从而提供更精细、适应性更强的错误管理方法。

下面是一个实现示例:GlobalExceptionHandle

internal sealed class GlobalExceptionHandle : IExceptionHandler

{

private readonly ILogger<GlobalExceptionHandle> _logger;

public GlobalExceptionHandle(ILogger<GlobalExceptionHandle> logger)

{

_logger = logger;

}

public async ValueTask<bool> TryHandleAsync(

HttpContext httpContext,

Exception exception,

CancellationToken cancellationToken)

{

_logger.LogError(

exception, "Exception: {Message}", exception.Message);

var problemDetails = new ProblemDetails

{

Status = StatusCodes.Status500InternalServerError,

Title = "Error"

};

httpContext.Response.StatusCode = problemDetails.Status.Value;

await httpContext.Response

.WriteAsJsonAsync(problemDetails, cancellationToken);

return true;

}

}

添加自定义异常处理

要将您自己的实现合并到 ASP.NET Core 请求管道中,需要执行两个步骤:IExceptionHandler

依赖注入: 注册服务。这通常是使用您的方法中的方法完成的。该服务通常使用单例生存期进行注册,因此请注意注入具有不同生存期的服务,这可能会导致冲突。

中间件注册: 在请求管道中包含 。此中间件负责利用已注册的实现来处理异常。您通常会在方法中使用该方法来实现此目的。

其他注意事项: 您可能还会遇到与此过程一起使用的情况。此方法有助于为常见异常生成格式化的“问题详细信息”响应,从而改进返回给客户端的错误消息的结构和清晰度。

builder.Services.AddExceptionHandler<GlobalExceptionHandle>(); 

builder.Services.AddProblemDetails();

您还需要调用以将 添加到请求管道中:

app.UseExceptionHandler();

链接异常处理程序

您可以堆叠多个实现,以创建分层的错误处理方法。这些处理程序将按照其注册顺序进行处理。这种灵活性允许对不同类型的异常进行精细控制。IExceptionHandler

例如,您可以使用异常作为流控制的一种形式。通过定义自定义异常(如 和),您可以将特定错误条件映射到适当的 HTTP 状态代码。这有助于创建更加结构化和可预测的 API 响应。

下面是一个实现示例:BadRequestExceptionHandle

internal sealed class BadRequestExceptionHandle : IExceptionHandler

{

private readonly ILogger<BadRequestExceptionHandle> _logger;

public BadRequestExceptionHandle(ILogger<BadRequestExceptionHandle> logger)

{

_logger = logger;

}

public async ValueTask<bool> TryHandleAsync(

HttpContext httpContext,

Exception exception,

CancellationToken cancellationToken)

{

if (exception is not BadRequestException badRequestException)

{

return false;

}

_logger.LogError(

badRequestException,

"Exception: {Message}",

badRequestException.Message);

var problemDetails = new ProblemDetails

{

Status = StatusCodes.Status400BadRequest,

Title = "BadRequest",

Detail = badRequestException.Message

};

httpContext.Response.StatusCode = problemDetails.Status.Value;

await httpContext.Response

.WriteAsJsonAsync(problemDetails, cancellationToken);

return true;

}

}

下面是一个实现示例:NotFoundExceptionHandle

internal sealed class NotFoundExceptionHandle : IExceptionHandler

{

private readonly ILogger<NotFoundExceptionHandle> _logger;

public NotFoundExceptionHandle(ILogger<NotFoundExceptionHandle> logger)

{

_logger = logger;

}

public async ValueTask<bool> TryHandleAsync(

HttpContext httpContext,

Exception exception,

CancellationToken cancellationToken)

{

if (exception is not NotFoundException notFoundException)

{

return false;

}

_logger.LogError(

notFoundException,

"Exception: {Message}",

notFoundException.Message);

var problemDetails = new ProblemDetails

{

Status = StatusCodes.Status404NotFound,

Title = "NotFound",

Detail = notFoundException.Message

};

httpContext.Response.StatusCode = problemDetails.Status.Value;

await httpContext.Response

.WriteAsJsonAsync(problemDetails, cancellationToken);

return true;

}

}

您还需要通过调用来注册两个异常处理程序:AddExceptionHandler

builder.Services.AddExceptionHandler<BadRequestExceptionHandle>(); 

builder.Services.AddExceptionHandler<NotFoundExceptionHandle>();

将首先执行并尝试处理异常。如果未处理异常,将执行下一步并尝试处理异常。

异常处理中的换档

虽然ASP.NET Core中间件在异常处理方面很好 ,但接口的引入提供了一种更加精简和灵活的方法。这种改进的系统允许集中管理和自定义处理逻辑,使 ASP.NET Core 8 项目中的错误管理更加高效和适应性强。

如果你喜欢我的文章,请给我一个赞!谢谢

标签: #net发生了无法处理的异常