【问题标题】:How to not throw exception in ASP.NET Web Api service?如何在 ASP.NET Web Api 服务中不抛出异常?
【发布时间】:2013-11-08 20:36:40
【问题描述】:

我正在构建一个 ASP.NET Web Api 服务,我想创建集中的异常处理代码。

我想以不同的方式处理不同类型的异常。我将使用 log4net 记录所有异常。对于某些类型的例外情况,我想通过电子邮件通知管理员。对于某些类型的异常,我想重新抛出一个更友好的异常,该异常将返回给调用者。对于某些类型的异常,我只想继续从控制器处理。

但是我该怎么做呢?我正在使用异常过滤器属性。我有这个代码工作。该属性已正确注册并且代码正在触发。我只想知道如果抛出某些类型的异常,我该如何继续。希望这是有道理的。

public class MyExceptionHandlingAttribute : ExceptionFilterAttribute
{
  public override void OnException(HttpActionExecutedContext actionExecutedContext)
  {
    //Log all errors
    _log.Error(myException);

    if(myException is [one of the types I need to notify about])
    {
      ...send out notification email
    }

    if(myException is [one of the types that we continue processing])
    {
      ...don't do anything, return back to the caller and continue
      ...Not sure how to do this.  How do I basically not do anything here?
    }

    if(myException is [one of the types where we rethrow])
    {
      throw new HttpResponseException(new HttpResponseMessage(StatusCode.InternalServerError)
      {
        Content = new StringContent("Friendly message goes here."),
        ReasonPhrase = "Critical Exception"
      });
    }
  }
}

【问题讨论】:

  • 异常过滤器仅在 WebAPI 消息管道的“返回”部分触发。因此,如果您依靠异常过滤器来处理您的异常,我认为没有一种简单的方法可以让请求重新进入管道以进行进一步处理。有关 WebAPI 扩展点的更多信息,请参阅MVC Poster

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


【解决方案1】:

对于某些类型的异常,我只想继续从控制器处理。但是我该怎么做呢?

通过写try..catch 你希望这种行为发生。见Resuming execution of code after exception is thrown and caught

为了澄清,我假设你有这样的事情:

void ProcessEntries(entries)
{
    foreach (var entry in entries)
    {
        ProcessEntry(entry);
    }
}

void ProcessEntry(entry)
{
    if (foo)
    {
        throw new EntryProcessingException();
    }
}

而当EntryProcessingException 被抛出时,你实际上并不关心并且想要继续执行。


如果这个假设是正确的:你不能用一个全局异常过滤器来做到这一点,因为一旦一个异常被捕获,就没有返回执行到它被抛出的地方。 C# 中的There is no On Error Resume Next,尤其是在使用过滤器处理异常时,如@Marjan explained

因此,从过滤器中删除 EntryProcessingException,并通过更改循环体捕获特定异常:

void ProcessEntries(entries)
{
    foreach (var entry in entries)
    {
        try
        {
            ProcessEntry(entry);
        }
        catch (EntryProcessingException ex)
        {
            // Log the exception
        }
    }
}

您的循环将愉快地旋转到其结束,但会抛出将由您的过滤器处理的所有其他异常。

【讨论】:

  • A try except 不会做,因为异常过滤器可以被视为一种“应用程序全局异常捕获器”并且不会(轻松)允许进一步处理消息,这似乎成为 OP 所追求的。
  • @Marjan OP 似乎需要针对特定​​异常的“On Error Resume Next”。如果没有针对该调用站点中该特定异常的try..catch,您将无法做到这一点,因为如果您没有捕获该异常,而是让它由过滤器处理,则无法返回它被抛出的位置。跨度>
  • 我知道,但是 try catch 也无助于他想做的事情:在一个位置进行所有异常处理:异常过滤器。异常过滤器由 WebAPI 框架触发,作为对“用户代码”抛出的异常的响应。
  • 是的。我正是这个意思。写得真好。
  • 谢谢。这是一个很好的解释。我最终完全按照您在上一个代码块中的建议进行了操作。
猜你喜欢
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多