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

时间:2017-12-14 07:10:29

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

我收到的任务是让我们的C#Webapi返回错误响应,格式如下:

{
    "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:

我正在应用在每个需要该属性的方法中抛出异常的Attribute。例如,我有一个名为“event”的实体的Odata Controller:

 [CustomAuthentication]
    [CustomEnableQueryAttribute(PageSize = 20)]
    public IQueryable<Event> Get()
    {
        (...)
        return result;
    }

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

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

1 个答案:

答案 0 :(得分:1)

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

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

class Hello extends React.Component {
handleFormSubmit = (item) => {
  const url = 'https://api.aladhan.com/timingsByCity?city='+item+'&country=US&method=2';
  fetch(url)
    .then((response) => {
        console.log(response);
     return response.json();
    })
    .then((json) => {
      this.setState({
        Fajir: json.Fajir,
        Sunrise: json.Sunrise,
        Dhuhr: json.Dhuhr
      });
    });
}
  render() {
    return <button onClick={() => this.handleFormSubmit(2)}>Click Me</button>;
  }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

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

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