Web Api Action过滤器调用两次

时间:2013-08-28 10:33:02

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

我的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());
        }
     }

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

UPD

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

3 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:3)

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

代码应该是这样的:

// 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非常聪明,即使多次注册也只能执行一次过滤器。此外,有些情况下您确实需要这样做。

答案 2 :(得分:2)

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

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

然后在filterConfig中我有

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

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