Использование пользовательского IHttpActionInvoker в WebAPI для обработки исключений
Я пытаюсь добавить пользовательский IHttpActionInvoker в мое приложение WebAPI, чтобы предотвратить необходимость в многократном повторении кода обработки исключений в моих методах действий.
На самом деле, похоже, не так много о том, как это сделать, кроме этой статьи. После написания моего IHttpActionInvoker в соответствии со статьей я добавил этот код:
GlobalConfiguration.Configuration.Services.Remove(typeof(IHttpActionInvoker),
GlobalConfiguration.Configuration.Services.GetActionInvoker());
GlobalConfiguration.Configuration.Services.Add(typeof(IHttpActionInvoker),
new MyApiControllerActionInvoker());
В метод в моем файле Global.asax. Теперь, когда вы выполняете вызов моего API, я получаю следующее исключение, возникшее в методе Remove():
The service type IHttpActionInvoker is not supported
У меня есть два вопроса.
-
Учитывая, что там не так много ужасно, что писать пользовательские классы IHttpActionInvoker - это хороший подход к решению обработки исключений в приложениях WebAPI?
-
Кто-нибудь знает, почему я получаю такое исключение при выполнении метода Remove()
и как лучше всего исправить эту конкретную проблему?
Ответы
Ответ 1
У меня была такая же ошибка, которую вы описали при попытке удалить службу.
Я обнаружил, что мне не нужно ничего удалять из глобальной конфигурации, поскольку это появляется, если вы зарегистрировали интерфейс в своем контейнере, тогда он разрешит это в первую очередь.
Например, я использую SimpleInjector и в моем global.asax у меня есть это:
container.Register<IHttpActionInvoker , MyApiControllerActionInvoker >();
// Register the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
Во время выполнения он исправляет зависимость MyApiControllerActionInvoker, когда требуется.
Затем вы можете выполнять обработку исключений в своем клиенте ActionInvoker, и любые зависимости, установленные в вашем конструкторе, будут правильно подключены. Причина, по которой я смотрела на ActionInvoker, заключалась в том, чтобы получить инсталляцию конструктора, так как для инъекции в атрибуты требуется инъекция свойств.
Кроме того, вместо удаления/вставки замена работает. (в Global.asax)
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker(fooService));
Ответ 2
Вместо этого вы решили зарегистрировать фильтр исключения? Вот несколько документов об этом:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
Вам не следует падать на уровень invoker-действия, если все, что вы хотите сделать, это обработать некоторые исключения определенным образом.
Ответ 3
Как для меня, он работает с IActionInvoker вместо IHttpActionInvoker. Насколько я понимаю, IHttpActionInvoker используется для вызовов async api, не так ли?
public class RepControllerActionInvoker : ControllerActionInvoker
{
ILogger _log;
public RepControllerActionInvoker()
: base()
{
_log = DependencyResolver.Current.GetService<ILogger>();
}
public override bool InvokeAction(ControllerContext controllerContext, string actionName)
{
try
{
return base.InvokeAction(controllerContext, actionName);
}
catch (Exception e)
{
_log.Error(e);
throw new HttpException(500, "Internal error");
}
}
}