【发布时间】: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