最佳实践:如何处理web api控制器中的错误和异常?

时间:2012-12-19 11:07:32

标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api

我正在开发一个项目,并且在所有客户端操作上都非常依赖web api,无论是帐户详细信息更新,添加了新的详细信息,还是使用ASP.NET Web Api和Backbone.js修改了所有内容

当前场景:

在当前的方案中,我从web api控制器返回一个布尔值,以指示操作是否成功。

示例:

[ActionName("UpdateAccountDetails")]
public bool PostAccountDetails(SomeModel model)
{
    bool updateStatus = _customService.UpdateAccountDetails(model);
    return updateStatus;
}

所以在对此操作进行ajax调用后,我会检查响应是否为true / false并显示错误或成功消息。

问题:

现在发生的事情是我开始在我的操作中获得异常,并且操作保持返回false,并显示错误消息。但我无法找到原因?

所以我想知道是否有一个标准的api响应结构,每个人都遵循这个结构?

我最初提出这个想法,让每个web api动作都返回此类

public class OperationStatus
{
    public bool Result { get; set; } // true/false
    public string Status { get; set; } // success/failure/warning
    public List<string> WarningMessages { get; set; }
    public List<string> ErrorMessages { get; set; }
    public string OtherDetails { get; set; }
}

这种变化将是一个重大变化,耗费时间和资源,所以我认为最好对此有第二/第三/第四意见。

请对此有所了解。

更新:

对于little help中的一些Mark Jones,我想出了这个

[ActionName("UpdateAccountDetails")]
public HttpResponseMessage PostAccountDetails(SomeModel model)
{
    bool updateStatus;
    string errorMessage;
    try{
        updateStatus = _customService.UpdateAccountDetails(model);
        if(updateStatus)
        {
            return Request.CreateResponse(HttpStatusCode.OK);
        }
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
    catch(Exception exception)
    {
        errorMessage = exception.Message;
        return Request.CreateResponse(HttpStatusCode.InternalServerError, errorMessage);
    }

    return updateStatus;
}

有没有想过这个?

2 个答案:

答案 0 :(得分:26)

你应该避免在控制器的动作中使用try / catch。

有很多方法可以解决您的问题。 最简单和最干净的解决方案可能是使用ActionFilter来处理异常,类似于:

public class ExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        Debug.WriteLine(context.Exception);

        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
        {
            Content = new StringContent("An error occurred!"),
            ReasonPhrase = "Deadly Exception"
        });
    }
}

然后您可以使用[ExceptionAttribute]装饰您的操作。 当然,您可以扩展它以针对不同类型的异常(业务异常,数据异常,IO异常等)采取不同的行为,并根据这些异常返回不同的状态代码和反馈。

我建议您阅读Fredrik Normen撰写的优秀文章 - “ASP.NET Web API异常处理” http://weblogs.asp.net/fredriknormen/archive/2012/06/11/asp-net-web-api-exception-handling.aspx

他提供了Web API异常处理技术的概述。

答案 1 :(得分:4)

而不是返回 HttpResponseMessage ,我会保持API相同,并在捕获异常时抛出 HttpResponseException 。像这样:

throw new HttpResponseException(
    new HttpResponseMessage(HttpStatusCode.InternalServerError) 
       { ReasonPhrase = errorMessage });

这样您就不会更改API的定义,它也可以用于您的GET操作,返回一些必须序列化的对象。如果您使用JQuery ajax方法发送请求,那么错误处理程序将捕获此信息,您可以在 errorThrown 参数中检索文本消息并相应地处理它。