Ответ 1
Хотя мне нравится ответ Дарина, он не работает в нашем случае, поскольку инфраструктура веб-API ASP.NET MVC подавляет/обрабатывает исключения внутренне и не перебрасывает, чтобы использовать метод Application_Error в Global.asax. Наше решение таково.
В итоге я создал пользовательский 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, чтобы убедиться, что это первый/последний обработчик. Способ работы обработчиков в веб-API осуществляется иерархически. Таким образом, первый обработчик, который будет попадать за запрос, будет последним обработчиком, который будет атакован. По крайней мере, это мое понимание, кто-то может исправить меня, если я ошибаюсь.
public static void ConfigureApis(HttpConfiguration config)
{
config.MessageHandlers.Insert(0, new PrincipalHandler());
}
Используя этот подход, мы можем теперь проверять каждый результат, возвращаемый в ответ от веб-API и контроллеров. Это позволяет нам обрабатывать любые записи, которые могут возникнуть в результате чего-то, что не возвращается, как мы ожидаем. Теперь мы можем изменить содержание возвращаемого ответа, чтобы IIS не вставлял страницы ошибок HTML по умолчанию, если он видит определенные коды состояния HTTP.
Единственная проблема, с которой я столкнулся, и я надеюсь, что они изменят ее в предстоящем выпуске веб-API, заключается в том, что они не отправляют исключение в резервную копию задачи, возвращаемой из базы .SendAsync(), Таким образом, единственная информация, которую мы должны пройти, - это код статуса HTTP и стараюсь дать разумный или вероятный ответ потребителю.