有没有从JSON Web服务返回错误状态的传统方式?

我有一个.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协议的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.'
}

(我实际上并不包括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在默认情况下做了这样的事情,但是具有稍微不同的属性和内容。 微软自己的Web API框架做了类似的事情。 相关问题中链接的JSend规范是另一种变体。

等等。

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

(是的,这非常冗长 - 主要是因为我一直在寻找相同类型的“通用约定”)。

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


不,没有任何单一的主要标准,尽管这可能很好。 如果你想让自己成为一个包含successdetails的标准,这可能是有用的,但这取决于你是如何使用它的。 我认为最大的好处就是当你至少在你所有的代码中实现一个标准的一致性时,例如http://ricardocovo.com/2012/03/08/asp-net-mvc-using-json-standard-responses - 因为,你的Ajax通话/

如果它符合您的需求,您的回答完全可以接受。 如果我正在使用API​​,我会将该错误响应看作“标准”,其中包含响应代码和说明,尽管我可能喜欢布尔success以便于使用。


我的2美分:

我会说,最重要的是你发回的状态码,因为响应是最好的错误指示器,并且在4xx和5xx范围内提供了很多选项......(即使你尝试从茶壶中获得HttpGET的一些咖啡,也可以使用418:D)

因为任何不是200的都是某种错误,并且http状态代码在这种情况下应该被使用,所以任何进一步的错误消息都不是真的必要的(错误描述是由状态代码隐含的)。 浏览器是做请求的人,他们不关心错误消息,只关心状态码。

任何额外的错误消息都可能会带走太多的信息,导致可能的黑客攻击。 我的意思是,返回一个403 Forbidden是足够的信息,你不应该也会返回一个消息,说“不允许,请使用'1234'作为密码,而不是”:)

链接地址: http://www.djcxy.com/p/48061.html

上一篇: Is there a conventional way of returning error statuses from JSON web services?

下一篇: How is "int main(){(([](){})());}" valid C++?