这个主题几乎总结了一下。我有一个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
}
});
}
答案 0 :(得分:1)
return BadRequest
不会抛出异常,这就是为什么不会通过异常过滤器。
它所做的就是创建一个BadRequestResult,它是IHttpActionResult的一个实现,它将状态代码设置为500并创建HttpResponseMessage。
我对NotFound有同样的需求,我做的是:
public class NotFoundWithMessageResult : IHttpActionResult
{
private readonly string message;
public NotFoundWithMessageResult(string message)
{
this.message = message;
}
public Task ExecuteAsync(CancellationToken cancellationToken)
{
//your code goes here
}
}
protected internal NotFoundWithMessageResult NotFound(string message, params object[] args)
{
return new NotFoundWithMessageResult(string.Format(message, args));
}
if (x == null)
{
return NotFound("The x id {0} was not found.", id);
}