Использование пользовательского 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");
        }
    }
}