我正在构建一个 RESTful API,我想控制所有可能的输出给我的消费者。我正在实现ExceptionFilterAttribute
过滤控制器中引发的所有异常。然而,这并不能让我控制在到达控制器代码之前我的应用程序中可能发生的错误——例如路由错误。默认行为发回一个标准的序列化 HttpError ,泄露了太多我喜欢的内部信息,例如控制器类名等。我想避免这种情况。改变这种行为的最佳方法是什么?
2 回答
您可以添加一个MessageHandler
来执行此操作。
MessageHandlers
在管道中首先和最后运行,允许您处理原始传入请求和原始传出响应。
例如:
public class ErrorHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.IsSuccessStatusCode)
{
Debug.WriteLine("something happened! - " + response.ReasonPhrase);
}
return response;
}
}
然后在你的注册GlobalConfiguration
config.MessageHandlers.Add(new ErrorHandler());
这基本上检查传出响应并检查状态代码是否为 2xx。如果没有,你可以用它做点什么——记录,或者重置响应的内容来隐藏你想隐藏的任何内容。
实际上,默认情况下,我们非常小心不要将内部信息泄露给远程客户端。如果请求来自本地机器以进行调试,我们将提供内部信息,但我们不会将其发送到远程客户端。如果您想查看远程客户端的响应可能是什么样子,请在您的配置中尝试以下设置:
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
您可能还想查看此博客文章以获取有关 WebAPI 错误处理的更多信息:
http://blogs.msdn.com/b/youssefm/archive/2012/06/28/error-handling-in-asp-net-webapi.aspx
If the defaults still don't work for you, then you should follow Filip's suggestion and just intercept the response with a message handler to send back anything you like.