在自定义 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."
};
}
}
有很多情况是异常过滤器无法处理的。例如:
- 控制器构造函数抛出异常。
- 消息处理程序抛出异常。
- 路由期间抛出异常。
- 响应内容序列化期间抛出异常。
我已收到任务,使我们的 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."
};
}
}
有很多情况是异常过滤器无法处理的。例如:
- 控制器构造函数抛出异常。
- 消息处理程序抛出异常。
- 路由期间抛出异常。
- 响应内容序列化期间抛出异常。