我有一个 .NET .ashx 处理程序,它接收 jQuery AJAX 帖子,将 Web 服务请求格式化到第三方服务并使用结果。成功后,它会使用相关信息实例化一个匿名对象并格式化 JSON 响应字符串。
如果出现 Web 服务错误,我会执行以下操作:
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.StatusDescription = wsResult.ErrorCode;
这使得 jQuery AJAX 错误回调可以轻松访问状态代码和描述;然而,我实现这一点的方式是相当武断的。
在做了一些阅读之后,我找不到以下问题的结论性答案:是否有一个公认的通用约定(或 - 甚至 - 规范)用于将错误状态返回到基于 JSON 的 AJAX 调用,它允许任何消费者知道期待什么,或者这与任何其他函数调用的返回类型一样任意?
那么,这是将错误状态返回给 AJAX 调用者的一种完全可以接受的方式,还是有一种“正确”的方式来格式化 JSON 错误响应?
最佳答案
正如其他人所说,没有普遍的约定。 REST“社区”仍处于在此类问题上寻求共识的过程中——可能永远无法达成共识。仅举几个例子:
状态码
默认情况下,ServiceStack.NET 是一个广泛使用的 C# REST 库 Web 服务框架,它返回带有状态代码的对象(或空响应),例如:201 Created
或者:200 OK
在验证错误的情况下(例如 ArgumentException
),它可能会执行例如:400 Bad Request
这已经是事情开始发生变化的第一个点。有些人喜欢400
诸如验证错误之类的状态代码 - 其他人没有,因为 400
确实表示请求格式本身的语法错误。
有些人更喜欢 422 Unprocessable Entity
对于验证错误,HTTP 协议(protocol)的 WebDAV 扩展,但在技术上仍然完全可以接受。
其他人认为您应该简单地采用 HTTP 协议(protocol)中未使用的错误状态代码之一,例如461
. Twitter 已经通过(以及其他)做到了这一点 420 Enhance Your Calm
通知客户他们现在受到速率限制 - 即使有(表面上)可接受(和推荐)的状态代码 429 Too Many Requests
已经为此目的。
等等。这都是哲学问题。
至于500 Internal Server Error
,同样适用 - 有些人认为它对各种错误响应都很好,其他人认为 5xx
错误应该只在异常时返回(真正意义上的 - 即异常错误)。如果错误确实是异常的,您通常不会想捕获机会传递任何实际的异常信息,这可能会透露太多关于您的服务器的信息。
引导我们在 JSON 结果中返回什么(如果有的话)?一样...
回复 200 OK
可能足以响应例如如果没有发生错误,则请求删除资源。同理,404 Not Found
足以告诉客户端无法执行请求的删除,因为找不到要删除的实体。在其他情况下,您可能需要更多。
有些人认为您应该在响应 header 中包含尽可能多的所需信息,通常只有 header 的空响应。例如,在创建时,返回 201 Created
并将创建的实体的 ID(作为资源 URI)放入 Content-Location
.不需要回复内容。
我个人认为,如果您要制作公共(public) API,最好同时返回适当的 header 和内容,即使内容有些多余。 IE。:
HTTP/1.1 404 Not found
Content-Type: application/json; charset=utf-8
...
{
'Success': false,
'Message': 'The user Mr. Gone wasn't found.'
}
(我实际上并不包括
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.'
}
}
ServiceStack.NET 做 something like this by default ,但属性和内容略有不同。微软自己的Web API 框架does something similar .
related question 中链接的 JSend 规范是另一种变体。
等等。
简而言之,不,没有任何通用约定 - 至少现在还没有。很多人(比我想的更多)都在研究它。但是,可能永远不会有。你的方法是完全可以接受的。
(是的,这很冗长 - 主要是因为我一直在寻找相同类型的“通用约定”一段时间)。
有关状态代码的更多信息,this is an excellent article (too long to quote here)
关于c# - 是否有从 JSON Web 服务返回错误状态的传统方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17293934/