【问题标题】:Web API 2.0 Exception HandlingWeb API 2.0 异常处理
【发布时间】:2017-10-11 15:36:37
【问题描述】:

我正在使用 Web API 2.0 创建自己的项目。 我的 Api 包含添加、获取和预订产品的功能。

我想处理异常,但有些问题我有点困惑。

我有一个控制器:ProdctController,动作方法为AddProdct

   [Route("~/CKService.svc/author/add")]
    [HttpPost]
    public IHttpActionResult AddProduct(ProductRequest request)
    {
        ProductManager.AddProduct(request.ProductId, request.ProductName, 
        request.Price);

        return Ok(new AddProductResponse()
        {
            Status = AddProductStatus.Success
        };)
    }

现在,如果产品已经存在,那么数据访问层会抛出DuplicateKeyException

我想像这样处理这个异常并返回响应:

  return Ok(new AddProductResponse()
    {
        Status = AddProductStatus.AlreadyExists
    };)
  1. 返回HTTP status code 200合理吗?
  2. 如果不将catch DuplicateKeyException 添加到我的控制器,我怎么能做到这一点,因为我认为这不是正确的方法。

谢谢

【问题讨论】:

  • 如果是错误,您永远不应该返回 HTTP 200。
  • 还有a lot关于ASP.NET Web API中的异常处理。
  • 409 冲突 - 将是一个合理的 HTTP 代码 reference
  • 您应该返回反映错误的 HTTP 状态,而不是您自己在“成功”方法中定义的任意代码。利用现有的、定义明确的标准代码。然后,您的响应具有任何通用 API 客户端都可以使用的内在语义含义。出现问题时返回“OK”实际上会误导客户端应用程序,即使您记录了它,而不是 RESTful API 的预期工作方式。
  • @ADyson 谢谢,我还是很困惑,例如,如果我有 book_seat 操作方法,但在这种情况下飞机已经满了,那么返回的正确状态码是什么?

标签: c# asp.net rest asp.net-web-api asp.net-web-api2


【解决方案1】:

这里有一个建议。 (我强调这只是您可用的众多选项之一

重构经理处理并返回添加产品的状态,然后让操作根据状态返回适当的响应代码。

[Route("~/CKService.svc/author/add")]
[HttpPost]
public IHttpActionResult AddProduct(ProductRequest request) {
    var status = ProductManager.AddProduct(request.ProductId, request.ProductName, request.Price);
    var response = new AddProductResponse() {
        Status = status
    };
    if(status == AddProductStatus.Success) {
        return Ok(response);
    }
    return BadRequest(response);
}

对于未按预期完成的请求,请避免返回 200 OK。这会误导提出请求的客户。

【讨论】:

【解决方案2】:

HTTP 200 不合理 - 它表示请求成功。请改用 4xx(错误)代码。 409(冲突)适合您已经存在的对象的情况。

见:HTTP response code when resource creation POST fails due to existing matching resource

捕捉异常完全没问题。未处理的异常将导致 500 错误(内部服务器错误),这无论如何都没有意义。 相反,您应该捕获异常并返回这样的 HTTP 错误 (Exception Handling ASP.NET):

 throw new HttpResponseException(
        Request.CreateErrorResponse(HttpStatusCode.Conflict, message))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 2012-05-04
    • 2016-12-02
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2016-04-25
    • 2015-10-18
    相关资源
    最近更新 更多