简体   繁体   English

在WebAPI中使用自定义IHttpActionInvoker进行异常处理

[英]Using Custom IHttpActionInvoker in WebAPI for Exception Handling

I'm trying to add a custom IHttpActionInvoker to my WebAPI application in order to prevent the need for lots of repeated exception handling code in my action methods. 我正在尝试将自定义IHttpActionInvoker添加到我的WebAPI应用程序中,以防止在我的操作方法中需要大量重复的异常处理代码。

There really doesn't seem to be much out there about how to do this other than this article . 除了这篇文章之外,关于如何做到这一点似乎并没有多少。 After writing my IHttpActionInvoker as per the article I added this code: 根据文章写了我的IHttpActionInvoker后,我添加了这段代码:

GlobalConfiguration.Configuration.Services.Remove(typeof(IHttpActionInvoker),
GlobalConfiguration.Configuration.Services.GetActionInvoker());

GlobalConfiguration.Configuration.Services.Add(typeof(IHttpActionInvoker),
new MyApiControllerActionInvoker());

Into a method within my Global.asax file. 进入我的Global.asax文件中的方法。 Now when executing a call to my API I get the following exception raised at the Remove() method: 现在,在执行对API的调用时,我在Remove()方法中引发了以下异常:

The service type IHttpActionInvoker is not supported

I guess I have two questions. 我想我有两个问题。

  1. Considering there doesn't seen to be an awful lot out there about writing custom IHttpActionInvoker classes is this considered a good approach to solve exception handling in WebAPI applications? 考虑到编写自定义IHttpActionInvoker类没有被认为是一个很糟糕的问题,这被认为是解决WebAPI应用程序中的异常处理的好方法吗?

  2. Does anyone know why I would get such an exception when executing the Remove() method and how best to fix this particular issue? 有谁知道为什么我会在执行Remove()方法时遇到这样的异常以及如何最好地解决这个特定问题?

I suffered the same error you describe when attempting to remove the service. 尝试删除服务时,我遇到了您描述的相同错误。

I discovered I didn't need to remove anything from the global config, as it appears if you've registered the interface in your container then it will resolve this first. 我发现我不需要从全局配置中删除任何内容,因为如果您在容器中注册了接口,它就会出现,然后它将首先解决此问题。

For example, I'm using SimpleInjector and in my global.asax I have this: 例如,我正在使用SimpleInjector,在我的global.asax中我有这个:

container.Register<IHttpActionInvoker , MyApiControllerActionInvoker >();
// Register the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver =
   new SimpleInjectorWebApiDependencyResolver(container);

At runtime, it is resolving MyApiControllerActionInvoker dependency when required. 在运行时,它在需要时解析MyApiControllerActionInvoker依赖项。

You can then perform exception handling in your customer ActionInvoker and any dependencies set in your constructor will be wired up correctly. 然后,您可以在客户ActionInvoker中执行异常处理,并且构造函数中设置的任何依赖项都将正确连接。 The reason I was looking at the ActionInvoker was to get the constructor injection, since injecting into Attributes appears to require property injection. 我查看ActionInvoker的原因是为了获取构造函数注入,因为注入Attributes似乎需要注入属性。

Also rather than the remove/insert, replace seems to work. 而不是删除/插入,替换似乎工作。 (in Global.asax) (在Global.asax中)

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker(fooService));

Have you considered registering an exception filter instead? 您是否考虑过注册例外过滤器? Here's some documentation about that: 这是关于它的一些文档:

http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling

You shouldn't have to fall down to the action invoker layer if all you want to do is handle some exceptions in a particular way. 如果你想做的只是以特定的方式处理一些异常,你不应该陷入动作调用者层。

As for me it works with IActionInvoker instead of IHttpActionInvoker. 至于我,它适用于IActionInvoker而不是IHttpActionInvoker。 As I understand, IHttpActionInvoker is used for the async api calls, isn't it? 据我了解,IHttpActionInvoker用于异步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");
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM