【问题标题】:ASP.NET Core, handle expected exceptionsASP.NET Core,处理预期异常
【发布时间】:2020-12-16 03:09:38
【问题描述】:

我正在 ASP.NET 核心中开发一个非常简单的 CRUD 控制器,现在我面临一个问题,即我需要处理错误,例如使用不存在的实体(返回 404)或创建副本(返回 400)。

所以现在我想知道在 ASP.NET Core 中获取预期错误并为它们返回正确状态代码的最惯用的方法是什么。

一种方法是在负责实际 CRUD 的服务中抛出异常并在控制器内部捕获它们:

/// Inside service...
public void Create(Entity entityDetails) {
  if (entityAlreadyExists(entityDetails)) {
    throw new EntityDuplicateException();
  }
  // ...
}

/// Inside controller...
[HttpPost("{operatorClientId}")] 
public void CreateEntity(Entity entityDetails) {
  try {
   _entityService.CreateEntity(entityDetails);    

    return Ok();
  } catch (EntityDuplicateException e) {  // Some self defined exception type
    return BadRequest(/* Some details about the entity */);
  }
}

这对我来说似乎有点重复,因为很多代码总是相同的,但乍一看它清楚地表明了 API 的期望。我认为当需要处理更多异常时,这也会变得有点混乱。

另一种方法是为 UseExceptionHandler 实现一个方法,其中所有异常类型的处理方式如下:

switch (exceptionHandlerPathFeature.Error)
{
    case EntityDuplicateException e:
        context.Response.StatusCode = 400;
        // More details to response here
        break;
    case EntityNotFoundException e:
        context.Response.StatusCode = 404;
        // More details to response here
        break;
    case {} e:
        context.Response.StatusCode = 500;
        // More details to response here
        break;
}

这将是处理预期(和意外)异常的一个地方。但是你第一眼看不到控制器会返回什么。并且在响应中获取有意义的错误消息所需的所有信息会变得更加困难(在控制器中,每个信息都是直接可用的,我需要使用 ExceptionHandler 将所有信息包装到异常中)。

【问题讨论】:

  • 您还可以从服务返回响应类型,包括成功/失败字段、失败原因和结果,而不是异常。然后您可以评估该响应并从中创建适当的 API 响应。使其成为泛型类型,您还可以避免大量重复代码。虽然这与使用异常非常相似,但它避免了创建异常上下文的开销。
  • 您可以创建一个中间件,在任何地方捕获相同的异常。

标签: c# asp.net-core


【解决方案1】:

异常,顾名思义,只能在特殊情况下使用,not for control flow。没有被发现或已经存在的实体并不例外;这是您应该在数据访问代码中明确处理的常见情况。另一方面,您的数据库中存在死锁。

不要让您的数据访问方法抛出异常,而是让它们返回类似于 (bool success, string errorMessage) 的元组。在控制器中,检查 success 成员 - 如果是 false,则将 errorMessage 返回给调用者。

至于您的全局异常处理程序,请保持通用。它应该只是将所有异常记录到一个中心位置,以便您可以定期检查这些日志以确定您的应用是否真的定期遇到异常情况 - 在这种情况下您需要修复它。

【讨论】:

    猜你喜欢
    • 2016-12-02
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2021-05-19
    • 2017-03-29
    相关资源
    最近更新 更多