2013-08-28 25 views
8

My WebApiフィルタメソッドOnActionExecutedが2回呼び出されています。 マイフィルタ(私はそれをできるだけシンプルにする):WebApi 2回呼び出されるアクションフィルタ

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; 
     } 
} 
+0

「Inject」属性がコメントアウトされていることに気付きました。フィルタを設定するNInject設定が2回追加される可能性がありますか?すべてのスタートアップコードの実行が終了した後、グローバルフィルタコレクションにフィルタのインスタンスが1つしかないことを確認しましたか? – levelnis

+0

全く何もありません。 'kernel.BindFilter (FilterScope.Global、1);' –

+0

を削除してコントローラを表示できますか? –

答えて

8

私はこの影響(この奇妙な行動があまりにもフィルタのいずれかをオーバーライドAllowMultipleプロパティによって固定され、偽を返す、またはfalseにAllowMultipleセットでAttributeUsage属性を適用することができ、疑いを持っていますデフォルトの実装でAllowMultipleフィルタの特性

少なくとも私たちのプロジェクトでは、これは助けになりました(私たちはAutofac経由でフィルタを注入しました)。

+1

これは私のために働いた! –

+6

'AllowMultiple'はハックに似ていますが、アクションフィルタを2回登録するものがあります。 –

+0

@ DanielLittle、これは正しい発言です。 –

2

これは、カスタムフィルタープロバイダーの登録が原因である可能性があります。これを行うと、デフォルトの登録を解除する必要があります。それ以外の場合は、カスタムフィルタで通常のフィルタを取得している場合は、2回登録され、結果として2回実行されます。 .NETは一度だけ、それは数回登録されている場合でも、フィルタを実行してくれているので

falseにように言ってきた
// 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はハックです:

コードは次のようなものでなければなりません。また、これが真実であることを必要とするシナリオもあります。

+0

このコードをお寄せいただきありがとうございますが、FilterProviderをActionDesctiptorFilterProviderタイプで検索するとエラーになります。シーケンスには一致する要素が含まれていません –

1

私にとっては、フィルタを2回指定しました。私のIOCの設定ファイルでは、私は

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

を持っていたそしてに、FilterConfigに私が

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

を持っていた私は、に、FilterConfigから行を削除し、すべてが良好でした。

関連する問題