是否有从JSON Web服务返回错误状态的传统方法?

Ant*_*t P 19 c# asp.net ajax jquery json

我有一个.NET .ashx处理程序,它接收一个jQuery AJAX帖子,将Web服务请求格式化为第三方服务并使用结果.成功时,它使用相关信息实例化一个匿名对象并格式化JSON响应字符串.

如果Web服务错误,我会执行以下操作:

context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.StatusDescription = wsResult.ErrorCode;
Run Code Online (Sandbox Code Playgroud)

这使得jQuery AJAX错误回调可以轻松访问状态代码和描述; 但是,我实现这个的方式是非常武断的.

在做了一些阅读之后,我无法找到以下问题的确定答案:是否存在可接受的通用约定(或 - 甚至 - 规范),用于将错误状态返回到基于JSON的AJAX调用,这允许任何消费者知道期待什么,或者这是任意其他函数调用的返回类型?

那么,这是一种将错误状态返回给AJAX调用者的完全可接受的方式,还是有一种格式化JSON错误响应的"正确"方式?

Jim*_*iTh 20

正如其他人所说,没有普遍的惯例.REST"社区"仍然在这些问题上找到一些共识 - 可能永远找不到共识.举几个例子:

状态代码

默认情况下,ServiceStack.NET是一种广泛使用的C#REST库 Web服务框架,它返回带有状态代码的对象(或空响应),例如:

201 Created

要么:

200 OK

在验证错误(例如ArgumentException)的情况下,它可以例如:

400 Bad Request

这已经是事情开始变化的第一点.有些人喜欢400验证错误之类的状态代码 - 其他人则不喜欢,因为在请求格式本身中400确实表示格式错误.

有些人更喜欢422 Unprocessable Entity验证错误,这是HTTP协议的WebDAV扩展,但在技术上仍然完全可以接受.

其他人认为您应该只使用HTTP协议中未使用的错误状态代码之一,例如461.Twitter已经(以及其他)420 Enhance Your Calm通过客户通知他们现在正在受到速率限制 - 即使有(表面上)可接受(和推荐)的状态代码429 Too Many Requests已经用于此目的.

等等.这都是哲学问题.

至于500 Internal Server Error,同样适用-有些人认为它是各种错误响应完全正常,有的则认为该5xx错误应该在例外返回(真正意义上的-即卓越的错误).如果错误确实非常特殊,那么您通常不希望抓住机会并传递任何实际的异常信息,这可能会显示您的服务器过多.

引导我们在JSON结果中返回什么(如果有的话)?一样...

响应

200 OK如果没有发生错误,则可能足以响应例如删除资源的请求.以同样的方式,404 Not Found足以告诉客户端无法执行请求的删除,因为找不到要删除的实体.在其他情况下,您可能需要更多.

有些人认为您应该在响应标头中包含尽可能多的所需信息,通常只有标题的空响应.例如,在创建时,返回201 Created并将创建的实体的ID(作为资源URI)放入其中Content-Location.无需回复内容.

我个人认为,如果你正在制作公共API,那么返回适当的标题和内容是个好主意,即使内容有点多余.即:

HTTP/1.1 404 Not found
Content-Type: application/json; charset=utf-8
...

{
   'Success': false,
   'Message': 'The user Mr. Gone wasn't found.'
}
Run Code Online (Sandbox Code Playgroud)

(我实际上并没有包含该Success属性,但我可能想要,根据我在设计API时的心态).

在DEBUG模式下运行时,我还包括内部服务调用的字符串表示形式 - 例如'Request': 'GetUser { id: 5 }',时间戳和堆栈跟踪.不过,这一切都是为了方便.只需基于简单的用户友好错误消息就可以轻松地为客户端编写代码404 Not found.但是,其他一些错误(例如验证)可能需要更多上下文.例如:

HTTP/1.1 422 Validation Error
Content-Type: application/json; charset=utf-8
...

{
   'Success': false,
   'Message': 'The request had validation errors.',
   'Errors':
   {
       'UserName': 'The user name must be provided.',
       'Email': 'The email address is already in use.'
   }
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,ServiceStack.NET会执行类似的操作,但属性和内容略有不同.微软自己的Web API框架做了类似的事情.相关问题中链接的JSend规范是另一种变体.

等等.

简而言之,不,没有任何普遍的惯例 - 至少还没有.很多人(比我更多地考虑它)正在努力.但是,仍然可能永远不会.而你的方法是完全可以接受的.

(是的,这是非常冗长的 - 主要是因为我一直在寻找相同类型的"普遍惯例").

有关状态代码的更多信息,这是一篇优秀的文章(这里引用的时间太长)