【问题标题】:WebApi Action filter called twiceWebApi Action 过滤器调用了两次
【发布时间】:2013-08-28 10:33:01
【问题描述】:

我的 WebApi 过滤方法 OnActionExecuted 被调用了两次。 我的过滤器(我让它尽可能简单):

   public class NHibernateActionFilter : ActionFilterAttribute
   { 
        //  [Inject]
        //   public ISessionFactoryProvider sessionFactoryProvider { get; set; }
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
           var a = 5;
           var b = a;
           //new BaseSessionProvider(sessionFactoryProvider).EndContextSession();
        }
    }

我的设置:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        //http://stackoverflow.com/questions/9521040/how-to-add-global-asp-net-web-api-filters
        FilterConfig.RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
    }

    public class FilterConfig
    {

        public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
        {
             filters.Add(new NHibernateActionFilter());
        }
     }

在调试器中,我用相同的actionExecutedContext 两次捕获OnActionExecuted。为什么?

UPD

Controller
public class BankSmsController : ApiController
{
         [AcceptVerbs(HttpVerbs.Get)]
         public int GetTest()
         {
             return 1;
         }
}

【问题讨论】:

  • 我注意到一个 Inject 属性被注释掉了——是否有一些 NInject 配置也设置了过滤器,所以它被添加了两次?是否确认在所有启动代码运行完毕后,全局过滤器集合中只有一个过滤器实例?
  • 根本没有ninject。我删除kernel.BindFilter<NHibernateActionFilter>(FilterScope.Global, 1);
  • 你能展示一下控制器吗?
  • 您的控制器和全局过滤器中可能直接有[NHibernateActionFilter]。因此它被执行了两次。
  • 我连接了我的控制器。它没有属性或动作

标签: asp.net-mvc asp.net-web-api action-filter


【解决方案1】:

我怀疑,这种奇怪的行为可以通过覆盖过滤器的 AllowMultiple 属性并返回 false 或应用 AttributeUsage 属性并将 AllowMultiple 设置为 false 来修复(这会影响 @ 的默认实现987654324@过滤器属性。

至少在我们的项目中这有所帮助(我们通过 Autofac 注入了过滤器)。

【讨论】:

  • 使用AllowMultiple 更像是一个hack,有些东西是注册动作过滤器两次。
  • @DanielLittle 可能的罪魁祸首是什么?
  • 就我个人而言,我在WebApiConfig 文件中定义了一次属性,并在我的基本控制器类中定义了一次。
【解决方案2】:

这可能是由于注册了自定义过滤器提供程序造成的。执行此操作时,您需要取消注册默认值。否则,如果您在自定义过滤器中获取常用过滤器,它们将被注册两次,因此会执行两次。

代码应该是这样的:

// remove default action filter provider
var defaultFilterProvider = config.Services.GetFilterProviders().Single(provider => provider is ActionDescriptorFilterProvider);
config.Services.Remove(typeof(IFilterProvider), defaultFilterProvider);

// add custom filter provider
config.Services.Add(typeof(IFilterProvider), new CustomFilterProvider(container));

如前所述,AllowMultiple 设置为 false 是一种 hack,因为 .net 足够聪明,即使已注册多次,也只能执行一次过滤器。此外,在某些情况下,您确实需要做到这一点。

【讨论】:

  • 感谢您提供此代码,但我无法找到具有 ActionDesctiptorFilterProvider 类型的 FilterProvider 它给了我错误序列不包含匹配元素
  • 取决于实际应用配置,但所有匹配的过滤器都应该被移除/替换:config.Services.RemoveAll(typeof(System.Web.Http.Filters.IFilterProvider), provider => provider is ActionDescriptorFilterProvider);
【解决方案3】:

对我来说,我已经指定了两次过滤器。在我的 IOC 配置文件中,我有

builder.Register(c => new SelectListFilter(c.Resolve<ClientManager>()))
        .AsActionFilterFor<Controller>()
        .InstancePerRequest();
        .RegisterFilterProvider();

然后在 filterConfig 我有

filters.Add(DependencyResolver.Current.GetService<IActionFilter>());

我从 filterConfig 中删除了该行,一切都变得更好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2015-08-19
    相关资源
    最近更新 更多