尽管我喜欢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 =>
{
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状态代码并尽力给消费者一个合理或可能的答案。