'return BadRequest'忽略ExceptionFilter

时间:2015-02-25 09:17:29

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

这个主题几乎总结了一下。我有一个ExceptionFilter,它强制项目中的开发人员只抛出一种允许通过的异常,任何其他异常都转换为泛型500异常。只要WebApi控制器方法确实返回BadRequest('某些消息')'但是,它没有通过异常过滤器。

问题是我必须遵守创建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);
}

此ALSO遍历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);
}

ExceptionFilter:

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
    }
  });
}

1 个答案:

答案 0 :(得分:1)

return BadRequest

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

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

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

  1. 使用我的自定义逻辑
  2. 创建IHttpActionResult的新实现
    
        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,我在其中创建方法
    2. 
      protected internal NotFoundWithMessageResult NotFound(string message, params object[] args)
      {
             return new NotFoundWithMessageResult(string.Format(message, args));
      }
      
      1. 像这样使用
      2. 
        if (x == null)
        {
            return NotFound("The x id {0} was not found.", id);
        }