【问题标题】:'return BadRequest' ignores ExceptionFilter'return BadRequest' 忽略 ExceptionFilter
【发布时间】:2015-02-25 09:17:28
【问题描述】:

这个主题几乎总结了它。我有一个 ExceptionFilter ,它强制项目中的开发人员只抛出它允许通过的一种类型的异常,任何其他异常都转换为通用 500 异常。但是,每当 WebApi 控制器方法确实“返回 BadRequest('some message')”时,它都不会通过异常过滤器。

问题是我在创建 Api 时必须遵守规范。规范指出,像 BadRequest(和其他 http 错误状态)之类的东西必须在响应中包含自定义 json 消息。抛出异常有效,但返回 BadRequest 无效。有什么想法吗?

ps。我知道我可以在 ActionFilter 中执行此操作,但感觉很尴尬,会在两个地方生成异常响应。

来自我的控制器的简单测试示例。 (没有做任何有用的事情,但会重现问题)。每当我使用高于 100 的值调用此方法时,它都会返回错误请求并且不会通过我的 ExceptionFilter:

[HttpGet]
[Route("values/{count}")]
public async Task<IHttpActionResult> GetValues(int count)
{
  int max = 100;

  if (count > max)
  {
    return BadRequest("'count' exceeded the maximum value of " + max);
  }

  var result = new List<string>();

  for (int i = 0; i < count; i++)
  {
    result.Add(Guid.NewGuid().ToString("n"));
  }

  return Ok(result);
}

此代码确实通过 ExceptionFilter(并转换为通用 500):

[HttpGet]
[Route("unhandledexception/{httpError}")]
public void UnhandledException(int httpError)
{
  throw new Exception("This is a thrown exception for testing purposes with http code " + httpError);
}

这也通过 ExceptionFilter(并在那里序列化为我的自定义 json):

[HttpGet]
[Route("handledexception/{httpError}")]
public void HandledException(int httpError)
{
  var error = new CustomApplicationError(httpError, 
    "Handled exception! Your input or request was wrong, " +
    "or something else, and now I'm telling you about it!");

  throw new HandledException(httpError, error, Request);
}

异常过滤器:

public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
  var task = base.OnExceptionAsync(actionExecutedContext, cancellationToken);

  return task.ContinueWith((t) =>
  {
    var handledException = actionExecutedContext.Exception as HandledException;

    if (handledException != null)
    {
      // <snip> serialize and set to response
    }
    else
    {
      // <snip> create generic 500 and set to response
    }
  });
}

【问题讨论】:

  • 发布控制器代码。
  • @FrebinFrancis。你去吧。谢谢。
  • 像 HandledException 这样的方法你在哪里写的?
  • 它在一个 TestController 中。测试我的动作过滤器和异常过滤器。
  • 您最好创建一个自定义异常过滤器属性,例如 asp.net/web-api/overview/error-handling/exception-handling

标签: .net asp.net-web-api


【解决方案1】:
return BadRequest

不会抛出异常,这就是为什么它没有通过异常过滤器。

它所做的只是创建一个 BadRequestResult,它是 IHttpActionResult 的一个实现,它将状态代码设置为 500 并创建 HttpResponseMessage。

我对 NotFound 也有同样的需求,我所做的是:

  1. 使用我的自定义逻辑创建 I​​HttpActionResult 的新实现

    public class NotFoundWithMessageResult : IHttpActionResult
    {
        private readonly string message;

        public NotFoundWithMessageResult(string message)
        {
            this.message = message;
        }

        public Task ExecuteAsync(CancellationToken cancellationToken)
        {
            //your code goes here
        }
    }
  1. 在我创建方法的地方创建一个 ControllerBase

protected internal NotFoundWithMessageResult NotFound(string message, params object[] args)
{
       return new NotFoundWithMessageResult(string.Format(message, args));
}
  1. 这样使用

if (x == null)
{
    return NotFound("The x id {0} was not found.", id);
}

【讨论】:

    猜你喜欢
    • 2016-09-12
    • 1970-01-01
    • 2016-06-07
    • 2020-11-04
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 2021-02-10
    • 2019-01-19
    相关资源
    最近更新 更多