【问题标题】:Best practice for error handling with ASP.NET Web API使用 ASP.NET Web API 处理错误的最佳实践
【发布时间】:2016-10-27 18:37:43
【问题描述】:

您能否阐明 Web API 错误管理的最佳实践。实际上,我不知道在我的 Api 请求中使用 try catch 是否是一个好习惯。

public Vb.Order PostOrderItem(Vb.Order order)
{
    if (OAuth.isValid(Request.Headers.GetValues("Token").Single()) != true)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        throw new HttpResponseException(httpResponseMessage);
    }
    if (!ModelState.IsValid)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
        throw new HttpResponseException(httpResponseMessage);
    }

    try
    {
        return Vb.Document.Generate(order);
    }
    catch (Exception ex)
    {
        logger.Error(ex);
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
        httpResponseMessage.Content = new StringContent(ex.Message);
        throw new HttpResponseException(httpResponseMessage);
    }

}

我觉得对服务器端代码使用 try catch 不是一个好习惯,因为我只是记录我的 catch 并重新抛出异常。

【问题讨论】:

    标签: c# asp.net asp.net-web-api exception-handling


    【解决方案1】:

    Web API 中的错误处理被认为是一个横切关注点,应该放在管道中的其他位置,这样开发人员就不需要关注横切关注点。

    你应该阅读Exception Handling in ASP.NET Web API

    如果 Web API 控制器抛出未捕获的异常会发生什么?经过 默认情况下,大多数异常都被转换为 HTTP 响应 状态码 500,内部服务器错误。

    还有Global Error Handling in ASP.NET Web API 2

    您应该尽量保持控制器精简。像原始代码一样的错误处理只会导致代码重复,开发人员需要注意的不必要的问题。开发人员应该关注核心关注点,而不是横切关注点。通过只关注核心问题,上面的代码将如下所示:

    [MyAuthentication]
    [MyValidateModel]
    public Vb.Order PostOrderItem(Vb.Order order)
    {    
        return Vb.Document.Generate(order);
    }
    

    为什么这么瘦?

    因为:

    if (OAuth.isValid(Request.Headers.GetValues("Token").Single()) != true)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        throw new HttpResponseException(httpResponseMessage);
    }
    

    可以移入Authentication Filters in ASP.NET Web API 2 可以在控制器/动作上本地应用或全局应用以返回相关响应。

    Model Validation in ASP.NET Web API这样的

    if (!ModelState.IsValid)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
        throw new HttpResponseException(httpResponseMessage);
    }
    

    也可以移动到过滤器中,例如:.

    public class MyValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答。只有一个额外的问题:elmah呢?工具很久没有更新了。按照你说的,我们已经不需要了,对吧?
    • 您仍然可以使用它。它是一个有用的工具。它补充了答案中提供的链接中提到的策略,因为您可以将错误传递/记录到位于外围的 elmah。 elmah 的可插拔特性展示了它如何专注于解决横切关注点。
    • 问题中的代码logger.Error(ex);怎么样?假设Vb.Document.Generate(order) 是一个数据库调用,如果发生异常我想记录一下。并将错误信息返回到json响应中。
    • @dc7a9163d9 会在错误处理程序中完成。您使用错误并返回用户友好的 json 响应。检查提供的有关异常处理的链接。
    • 虽然是个好建议,但这个答案在 IMO 中太模糊了。是的,这是一个跨领域的问题。是的,它应该放在控制器动作之外。但是这个建议适用于任何 API 框架。这个问题专门针对 ASP.NET Web API。答案可能在链接中,但仅链接的答案并不好。关于保持控制器精简的其余答案可以完全删除 IMO。
    【解决方案2】:

    请参考此链接Exception Handling in ASP.NET Web API - A Guided Tour。有 4 级异常处理管道:

    • 1 级 - HttpResponseException
    • 2 级 - 异常过滤器
    • 3 级 - 日志记录
    • 4 级 - 异常处理程序

    Web API 在异常处理方面为我们提供了极大的灵活性。回顾一下:

    • 使用 HttpResponseException 或快捷方法在操作级别处理未处理的异常。
    • 使用异常过滤器处理多个操作和控制器上的特定未处理异常。
    • 使用 ExceptionLogger 记录任何未处理的异常。
    • 使用异常处理程序(每个应用程序一个)来处理应用程序范围内的任何未处理的异常。

    【讨论】:

      【解决方案3】:

      有很多方法,每一个都在逻辑对象图上更上一层楼;

      本文将它们全部列出; http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine

      我发现使用一种更高级别的方法来避免重复代码很有用。

      【讨论】:

      • 这是关于 MVC,而不是 Web API。
      猜你喜欢
      • 2016-06-06
      • 1970-01-01
      • 2011-05-30
      • 2013-05-04
      • 2012-05-30
      • 2015-12-02
      相关资源
      最近更新 更多