尽管我喜欢 Darin 的回答,但它在我们的案例中不起作用,因为 ASP.NET MVC Web API 框架在内部抑制/处理异常,而不是重新抛出以命中 Global.asax 中的 Application_Error 方法。我们的解决方案是这样的。
我最终创建了一个自定义 DelegatingHandler ,如下所示:
public class PrincipalHandler : DelegatingHandler
{
protected const string PrincipalKey = "MS_UserPrincipal";
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
setAnonymousPrincipal();
request = InitializeIdentity(request);
return base.SendAsync(request, cancellationToken)
.ContinueWith(r =>
{
// inspect result for status code and handle accordingly
return r.Result;
});
}
}
然后我将它插入到 HttpConfiguration 中以确保它是第一个/最后一个被命中的处理程序。处理程序在 Web API 中的工作方式是分层的。因此,每个请求要命中的第一个处理程序将是响应命中的最后一个处理程序。至少这是我的理解,如果我错了,请随时纠正我。
public static void ConfigureApis(HttpConfiguration config)
{
config.MessageHandlers.Insert(0, new PrincipalHandler());
}
通过使用这种方法,我们现在可以检查从 Web API 和控制器的任何响应中返回的每个结果。这使我们能够处理由于某些内容未按预期返回而可能需要发生的任何日志记录。我们现在还可以更改返回的响应内容,以便 IIS 在看到某些 HTTP 状态代码时不会插入任何默认的 HTML 错误页面。
我唯一遇到的问题是,我希望他们在即将发布的 Web API 版本中对其进行更改,即他们没有在从 base.SendAsync() 返回的任务上发送异常备份。所以我们唯一需要通过的信息就是HTTP状态码,并尽力给消费者一个合理或可能的答案。