【问题标题】:What response code should we send on exception - WebAPI?我们应该在异常时发送什么响应代码 - WebAPI?
【发布时间】:2014-07-10 10:40:31
【问题描述】:

我正在写Web-API 方法。一种这样的方法类似于

public IHttpActionResult Post([FromBody]MyDTO)
{
   //validations 

   try
   {
      InsertInToDB(MyDTO.SomeField);
   }
   catch(Exception ex)
   {
      // Say some exception has occurred while inserting in to DB. For eg. SomeField is not a acceptable value.
      // What is the response that I should send to the API user ?
      // Notfound, BadRequest does not seem to be fit in this case.
   }

}

注意:InsertIntoDB 返回 void

现在,如果该方法中出现一些异常,我应该发送给用户的HttpStatusCode 应该是什么?

NotFoundBadrequest 响应似乎不适合这种情况。有什么想法吗?

【问题讨论】:

  • HttpStatusCode.InternalServerError怎么样
  • 500 内部服务器错误怎么办?
  • 关于 SO 上的 HTTP 状态码有 很多 的讨论,这种情况并不是唯一的。 4xx 范围用于客户端错误,5xx 用于服务器错误。如果在没有先验证输入的情况下捕获Exception,则无法区分客户端错误(缺少输入)或服务器错误(SQL 无法访问)。
  • 尝试使用搜索 :) HTTP Status Code for database is down.
  • @CodeCaster:哎呀。我的错。现在明白了。非常感谢:)

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


【解决方案1】:

您发回的异常取决于几件事。

首先,用户是否向您发送了不良信息?还是你的服务器搞砸了?

4XX 状态码用于用户搞砸的时候。

4XX:

如果问题是用户发送了格式错误的请求,则返回400 Bad Request

如果问题是您使用 POST 来确定资源是否存在(例如通过搜索),那么如果他们尝试访问的资源未找到,则 404 Not Found 将是合适的。

如果问题是插入此值会导致现有值出现问题(假设它们具有完全相同的名称,但它们不应该;或其他一些验证式错误:409 Conflict 是合适的。

5XX

5XX 状态码用于您的代码出错时。用户做对了一切,但你还是搞砸了。

例如,if your database is down, a 500 or 503 is appropriate

顺便说一句,抓住毯子Exception 很糟糕。在这种情况下,如果您有不同的验证,您应该创建可以在出现验证错误时抛出的异常类;以区别于用户编写的所有内容但代码出错。

在这种情况下,我会:

ValidationFailedException -> Web 层返回 400 ConflictException -> Web 层返回 409 ItemDoesNotExistException -> Web 层返回 404

请注意,您的数据层不应依赖于 Web 层或任何与 Internet 相关的内容。这意味着您应该有内部异常类;抛出这些,并使用它们在您的 Web 层中生成适当的 HttpException

【讨论】:

  • 问题是someField 不是数据库接受的有效名称。那么,在这种情况下,我应该使用什么异常?我也不能选择Conflict :(
  • 如果用户输入了一个他们不应该有的值而搞砸了,这是一个错误的请求(400)。我已经编辑了我的答案以提供更多细节。至于你应该使用哪个异常,你应该为数据层创建自己的异常,然后在 Web 层处理这些异常以抛出 Web 相关异常(如Bad Request)。
  • 谢谢乔治。很好的解释。但还有一个问题:What if the invoked Stored Procedure in the DB does not exist?在这种情况下,我的 DB 层会给我一个 SQL exception 以及我现在应该抛出什么响应代码??
  • 嗯。为什么调用的存储过程不存在?您不会让您的用户输入他们自己的存储过程名称来运行,是吗?如果你是,我们有更深层次的问题。应该从不出现用户知道他们正在执行存储过程的情况,他们也不应该关心。如果您的代码有误,请立即花 10 秒时间进行修复。重建,重新部署。您必须更详细地(在您的问题中)这个特定用例;但从你告诉我的情况来看,我们遇到了更大的问题。
  • 谢谢乔治。我会回过头来回顾一下我到底在做什么然后回来。感谢您的洞察力
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2012-06-13
  • 2013-01-23
  • 2018-05-23
  • 1970-01-01
  • 2020-08-06
相关资源
最近更新 更多