什么是更好的Web API错误响应

时间:2014-02-14 19:02:22

标签: exception-handling asp.net-web-api httpresponse

1. return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No product with ID = 1");

2. var resp = new HttpResponseMessage(HttpStatusCode.NotFound) { Content = new StringContent("No product with ID = 1") };
   throw new HttpResponseException(resp);
用于WebAPI中的异常处理的

This guideline描述了上述两种方法。

我们应该何时return Request.CreateErrorResponse(#1)以及我们应该何时throw an HttpResponseException(#2)?

2 个答案:

答案 0 :(得分:1)

我得出的结论是,客户端代码在两种情况下都会有相同的行为,返回ErrorResponse或抛出ResponseException。重要的是我们希望将多少信息发送回客户端,以及当它们在服务器端发生时我们将如何处理错误。

所以我个人决定采用僵硬的方式,即在发生异常时抛出异常并向客户端提供简短(描述性)消息,而不是服务器端异常的内部细节。

从技术上讲,我选择了here提到的方法(作为类似问题的公认答案)。来自那个答案的脚本......

  

“从api控制器操作中抛出异常并有异常   过滤器已注册,处理异常并设置适当的   对行动执行上下文的回应“

在我的情况下,我使用了一个简单的实现,其中我创建了一个继承的异常类HttpApiException,它总是被抛回给用户。对于处理/预期情况,我的代码会直接使用适当的Error Code和自定义消息抛出它。否则,全局过滤器UnhandledExceptionAttribute将使用默认的Error Code 500和默认异常消息来处理它。

<强> HttpApiException

public class HttpApiException : HttpResponseException
{
    public HttpApiException(HttpResponseMessage message) : base(message) { }

    public HttpApiException(HttpStatusCode code) : base(code) { }
}

<强> UnhandledExceptionAttribute

public class UnhandledExceptionAttribute : ExceptionFilterAttribute 
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (!(context.Exception is HttpApiException))
        {
            throw new HttpApiException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { 
                Content = new StringContent(context.Exception.Message), ReasonPhrase = "An error occured while processing the request" 
            });
        }
    }
}

注册全局过滤器

GlobalConfiguration.Configuration.Filters.Add(new UnhandledExceptionAttribute());

示例控制器代码

if (new User("hello", "world").Exists()) { 
    // do something, if there will any error that will be directed towards global filter for un-handled exceptions
}
else
    throw new HttpApiException(new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("Invalid user name or password.") });

注意:我没有在单个代码块中添加任何try - catch { },因为所有未知/未处理的异常都会转到UnhandledExceptionAttribute

答案 1 :(得分:0)

首选#1为Request.CreateErrorResponse提供内容协商的错误响应。示例:ajax客户端发出基于json的请求将获得json格式的错误响应,使其能够读取它。

*可能出现的一种可能性是格式化程序本身无法编写响应并在写入con-neg响应时抛出异常。在这种情况下,内容协商的响应可能是不可能的。目前,web api不会返回任何细节以响应这些场景,但您可以使用全局错误处理功能来记录这些异常。 简而言之,您不必担心这种情况,因为这很少见,如果您使用的是Web API的默认格式化程序,那么您应该很好。