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

Alb*_*orz 6 c# asp.net lambda asp.net-web-api

我在我的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
}
Run Code Online (Sandbox Code Playgroud)

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

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        //Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的WebApiConfig类中注册它

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

Cod*_*ter 1

唯一ExceptionFilterAttribute适用于操作方法中引发的异常,请参阅ASP.NET Web API 中的异常处理 - 异常过滤器。您的代码将在结果实现期间引发异常,从而导致SerializationException.

\n\n

如ASP.NET Web API 2 中的全局错误处理中所述:

\n\n
\n

一些未处理的异常可以通过异常过滤器进行处理,但是异常过滤器可以\xe2\x80\x99t处理许多情况。例如:

\n\n
    \n
  • 控制器构造函数抛出异常。
  • \n
  • 消息处理程序引发的异常。
  • \n
  • 路由期间抛出异常。
  • \n
  • 响应内容序列化期间引发异常
  • \n
\n
\n\n

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

\n\n
\n

我们提供了两个新的用户可替换服务:IExceptionLogger 和 IExceptionHandler,用于记录和处理未处理的异常。这些服务非常相似,但有两个主要区别:\n 我们支持注册多个异常记录器,但仅支持一个异常处理程序。

\n\n
    \n
  1. 异常记录器总是被调用,即使我们\xe2\x80\x99要中止连接。
  2. \n
  3. 仅当我们\xe2\x80\x99仍然能够选择要发送的响应消息时,才会调用异常处理程序。
  4. \n
\n
\n\n

请参阅如何在全局范围内记录 C# MVC4 WebAPI 应用程序的所有异常?两者的实施。

\n\n

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

\n\n
var result = list.Select(a => GetData(a)).ToList();\n
Run Code Online (Sandbox Code Playgroud)\n