C# 如何在ASP.NET Web Api服务中不引发异常?

C# 如何在ASP.NET Web Api服务中不引发异常?,c#,asp.net,.net,exception-handling,asp.net-web-api,C#,Asp.net,.net,Exception Handling,Asp.net Web Api,我正在构建一个ASP.NET Web Api服务,并希望创建集中的异常处理代码 我希望以不同的方式处理不同类型的异常。我将使用log4net记录所有异常。对于某些类型的例外情况,我希望通过电子邮件通知管理员。对于某些类型的异常,我希望重新显示将返回给调用方的更友好的异常。对于某些类型的异常,我只想从控制器继续处理 但是我该怎么做呢?我正在使用异常过滤器属性。我有这个代码。属性已正确注册,代码正在触发。我只是想知道如果抛出某些类型的异常,我如何继续。希望这是有道理的 public class My

我正在构建一个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"
      });
    }
  }
}
对于某些类型的异常,我只想从控制器继续处理。但是我该怎么做呢

通过编写
try..catch
,您希望在哪里发生这种行为。看

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

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

void ProcessEntry(entry)
{
    if (foo)
    {
        throw new EntryProcessingException();
    }
}
当抛出
EntryProcessingException
时,实际上您并不关心,而是希望继续执行


如果这个假设是正确的:您不能使用全局异常过滤器来实现这一点,因为一旦捕获到异常,就不会将执行返回到抛出异常的位置。在C#中,尤其是当使用筛选器作为处理异常时

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

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

循环将愉快地旋转到终点,但会引发所有其他异常,这些异常将由过滤器处理。

异常过滤器仅在WebAPI消息管道的“返回”部分触发。因此,如果您依赖异常过滤器来处理异常,我认为没有一种简单的方法可以让请求重新进入管道进行进一步处理。有关WebAPI扩展点的详细信息,请参阅。try-except将不起作用,因为异常筛选器可以被视为“应用程序全局异常捕获器”的一种类型,并且(很容易)不允许进一步处理消息,这似乎是OP所追求的。@Marjan OP似乎希望对特定异常执行“下一步出错恢复”。如果没有对调用站点中的特定异常执行
try..catch
,则无法执行此操作,因为如果您没有捕获该异常,而是让它由筛选器处理,则无法返回到抛出它的位置。我知道,但是,try-catch也无助于他想要做的事情:在一个位置(异常过滤器)执行所有异常处理。异常过滤器由WebAPI框架触发,作为对“user code.Yay”引发的异常的响应。这就是我的意思。写得好,谢谢。这是一个很好的解释。我最终完全按照你在上一个代码块中的建议做了。