1

我想知道如何为ASP.NET Web API 控制器抛出的HttpResponseException异常编写文档注释?问题是,通常你会为每种情况抛出不同类型的异常,因此为每种异常类型编写文档注释,例如/// <exception cref="ResourceNotFound">Resource not found</exception>. 但是,对于 HttpResponseException,StatusCode异常的属性是识别错误情况的原因。

我应该如何记录HttpResponseException可能引发的每种情况,每种情况都由状态代码标识,对应于您如何编写/// <exception></exception>每种异常类型的注释?

4

2 回答 2

1

TL;DR 版本:主要使用客户可以采取行动的代码和信息来设计您的异常响应。尽可能利用标准 HTTP 状态代码。记录您在 HTTP 规范之外提供的内容,以指导客户端应用程序的行为。其次,在可行的情况下,提供客户开发人员可用于开发和故障排除的信息。

在为基于 HTTP 的 API 设计错误响应时,我会问自己,基于这些错误响应,客户端会触发哪些期望和相应的行为。当客户端收到 500 的 HTTP 状态代码时,它可以假设服务器发生了某种“故障”,从而无法正确处理请求。状态代码 500的HTTP 规范说,当另一个代码无法正确分配时,这是一种包罗万象的状态代码;除了知道服务器刚刚“繁荣”之外,对客户没有太大帮助。但是,有一个 HTTP 状态代码 503 Service Unavailable,它通过Retry-AfterHTTP 标头向客户端提供有关中断可能持续多长时间的信息。

在评论中的具体示例中,告诉客户端存在数据库异常并不是很有用,因为客户端可能对此无能为力。我会在服务器端记录有关异常的详细信息以供操作员/开发人员使用,并让 HTTP 状态代码通知客户端该问题。

我做的唯一例外是在请求无法解析时提供有关意外或丢失元素(等)的详细信息。我将使用 HTTP 状态代码 400 Bad Request 将其作为响应的一部分发送。客户端应用程序可能无法对这些信息做任何事情,但客户端开发人员会非常感激它。

于 2012-11-19T16:27:34.023 回答
0

我找到了一种解决方案,可以让我在 Web API 控制器方法中记录错误案例,就像对普通 C# 异常所做的那样 - 将要用于标记错误的每个 HTTP 状态代码映射到HttpResponseException. 这解决了我的特殊问题,这只是在 Web API 控制器方法的文档注释中描述错误情况。

以以下代码为例:

public class HttpNotFoundException : HttpResponseException
{
    public HttpNotFoundException(string reason)
        : base(new HttpResponseMessage { StatusCode = HttpStatusCode.NotFound, ReasonPhrase = reason })
    { }
}

public class HttpInternalServerError : HttpResponseException
{
    public HttpInternalServerError(string reason)
        : base(new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = reason })
    { }
}

public class ResourceApiController : ApiController
{
    IRepository Repository { get; set; }

    /// <summary>
    /// Delete a resource.
    /// </summary>
    /// <param name="id">Resource ID.</param>
    /// <exception cref="HttpNotFoundException">Resource not found.</exception>
    /// <exception cref="HttpInternalServerError">An internal error was detected, for instance in database service.</exception>
    public void DeleteResourceById(string id)
    {
        try
        {
            Repository.Delete(id);
        }
        catch (WebResourceNotFoundError)
        {
            throw new HttpNotFoundException(string.Format("Build '{0}' not found", id));
        }
        catch (DatabaseServiceException)
        {
            throw new HttpInternalServerError("Database service operation failed");
        }
    }
}
于 2012-11-20T08:30:48.650 回答