在自定义 ExceptionFilterAttribute 中创建错误响应时忽略 HttpError(如果在另一个属性中抛出异常)

HttpError is ignored when creating an error response in a custom ExceptionFilterAttribute (if the exception is throwed in another attribute)

我已收到任务,使我们的 C# Webapi return 始终使用以下格式进行错误响应:

{
    "error": {
        "code": 15,
        "message": "My custom error message"
    }
}

因此我注册了自己的 ExceptionFilterAttribute:

 public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
    {

        class CustomError
        {
                public int code { get; set; }
                public String message { get; set; }
        }

 public override void OnException(HttpActionExecutedContext context)
            {

                if (context.Exception is BaseException)
                {
                    BaseException exception = (BaseException)context.Exception;
                    HttpError error = new HttpError();
                    CustomError customError = new CustomError
                    {
                        code=exception.CustomError.code,
                        message=exception.CustomError.message
                    };
                    error.Add("error", customError);
                    context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, error);
                }
                else
                {
                    context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
                }
            }

当在控制器中抛出异常时,这工作得很好。但是如果异常是在属性(AuthorizeAttribute 或 EnableQueryAttribute)中抛出的,尽管调用了我的自定义 ExceptionFilter 并执行了相同的代码,生成的响应将忽略给定的 HttpError 并且响应具有以下主体:

  {
    "error": {
        "code": "",
        "message": ""
    }
}

我不是很擅长c#,我很确定我做错了什么,但我不知道是什么:S

提前致谢。

编辑 1:

我正在应用在每个需要属性的方法中抛出异常的属性。例如,我有一个名为 "event":

的实体的 Odata 控制器
 [CustomAuthentication]
    [CustomEnableQueryAttribute(PageSize = 20)]
    public IQueryable<Event> Get()
    {
        (...)
        return result;
    }

如前所述,如果在控制器主体中抛出异常,则会调用我的 CustomExceptionFilter,并正确创建自定义响应。

但是如果在 CustomAuthenticationAttribute 或 CustomEnableQueryAttribute 中抛出异常,那么尽管调用了我的 CustomExceptionFilter 并执行了完全相同的代码,但正文响应是错误的(参见示例)。

过滤器仅适用于控制器,但对于全局错误,您需要在 WebAPI 中使用全局错误过滤器。

要处理属性抛出的错误,您需要创建全局错误处理程序:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling

class OopsExceptionHandler : ExceptionHandler
{
    public override void HandleCore(ExceptionHandlerContext context)
    {
        context.Result = new TextPlainErrorResult//you have to create this class
        {
            Request = context.ExceptionContext.Request,
            Content = "Oops! Sorry! Something went wrong." +
                      "Please contact support@contoso.com so we can try to fix it."
        };
    }
}

有很多情况是异常过滤器无法处理的。例如:

  1. 控制器构造函数抛出异常。
  2. 消息处理程序抛出异常。
  3. 路由期间抛出异常。
  4. 响应内容序列化期间抛出异常。