如何在通过 lambda 表达式引发异常时全局处理 asp.net web api 中的异常

How to globally handle exceptions in asp.net web api when exception is raised through lambda expression

我的 Web api 项目中有一个全局异常处理程序。这工作正常,除非通过 lambda 表达式引发异常。 我在下面提供了示例代码:

[HttpGet]
public IHttpActionResult Test()
{
    //Throw new Exception();// this exception is handled by my ExceptionHandler
    var list = new List<int>();
    list.Add(1);
    IEnumerable<int> result = list.Select(a => GetData(a));
    return Ok(result);
}

private static int GetData(int a)
{
    throw new Exception();//This is not handled by my global exception handler
}

这是我的全局异常处理程序

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        //Do something
    }
}

我在我的 WebApiConfig 中注册了它 class

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { action = "Get", id = RouteParameter.Optional }
        );
        config.Filters.Add(new ExceptionHandlerAttribute());
    }
}

ExceptionFilterAttribute 仅适用于 在您的操作方法中 抛出的异常,请参阅 Exception Handling in ASP.NET Web API - Exception Filters。您的代码将在结果具体化期间抛出异常,从而导致 SerializationException

Global Error Handling in ASP.NET Web API 2 中所述:

Some unhandled exceptions can be processed via exception filters, but there are a number of cases that exception filters can’t handle. For example:

  • Exceptions thrown from controller constructors.
  • Exceptions thrown from message handlers.
  • Exceptions thrown during routing.
  • Exceptions thrown during response content serialization.

注册异常处理程序或记录器并采取适当的行动:

We provide two new user-replaceable services, IExceptionLogger and IExceptionHandler, to log and handle unhandled exceptions. The services are very similar, with two main differences: We support registering multiple exception loggers but only a single exception handler.

  1. Exception loggers always get called, even if we’re about to abort the connection.
  2. Exception handlers only get called when we’re still able to choose which response message to send.

请参阅 this answer in How do I log ALL exceptions globally for a C# MVC4 WebAPI app? 以了解两者的实现。

你当然也可以在你的控制器中实现可枚举,导致异常被抛出并由异常过滤器处理:

var result = list.Select(a => GetData(a)).ToList();