グローバルASP.Net Web APIフィルターを追加する方法?


98

(を使用してSystem.Web.Http.Filters.ActionFilterAttribute)Web APIフィルターを作成しましたが、ASP.Net MVC 4内で機能させることができません。RegisterGlobalFilters()メソッドに追加しようとしましたが、機能しませんでした。

では、ASP.Net MVCでホストされているWeb APIを使用している場合、どのようにフィルターを登録するのでしょうか。

回答:


110

私のGlobal.asaxにある次のコードは私にとってはうまくいきます:

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

protected void Application_Start()
{
  RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}

6
誰かがここで何が起こっているのか説明できますか?グローバルフィルターが2セットあるのはなぜですか?それは「グローバル」を矛盾したものにしないのですか?
ルークプレット

6
1つのフィルターセットはMVC用で、もう1つはWeb API用です。これらは2つの独立したものであり、通常は一方のフィルターをもう一方に適用する必要はありません。
シェーンコートリル

2
WebApiフィルターが2回呼び出されます。誰かこの問題がありますか?
アンドリューカラシニコフ2013

87

この回答はMVC 5 / Web API 2まで当てはまることに注意してください

短い答え: MVCフィルターとWeb APIフィルターは相互互換性がなく、グローバルに登録する場合は、それぞれに適切な構成クラスを使用する必要があります。

長い答え: ASP.NET MVCとWeb APIは意図的に同じように機能するように設計されていますが、実際には異なる生き物です。

Web APIはSystem.Web.Http名前空間の下にありますが、MVCはSystem.Web.Mvc名前空間の下にあります。2つは喜んで隣り合って存在しますが、1つはもう1つを含みません。プログラミングモデルの類似性にもかかわらず、基礎となる実装は異なります。MVCコントローラーとWeb APIコントローラーが異なるベースコントローラークラスを継承するのと同じように(MVCは単に名前が付けられController、Web APIは名前が付けられますApiController)MVCフィルターとWeb APIフィルターは異なるFilterAttributeクラスから継承します(この場合、両方とも同じ名前を共有しますが、別々のクラスであり、それぞれの名前空間で)。

WebActivatorでプロジェクトテンプレートを使用している場合HttpConfiguration、Web APIグローバルフィルターは、RegisterメソッドWebApiConfig.cs で使用可能なオブジェクトを通じて登録されます。

public static void Register(HttpConfiguration config)
{
    //stuff before
    config.Filters.Add(new MyWebApiFilter());
    //stuff after
}

または、global.asax.cs内:

GlobalConfiguration.Configuration.Filters.Add(new MyWebApiFilter());

Mvcグローバルフィルターは、GlobalFilterCollectionオブジェクトを使用して登録されます。これはRegisterGlobalFilters、WebActivatorを使用しているプロジェクトのFilterConfig.cs のメソッドを通じて利用できます。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //stuff before
        filters.Add(new MyMvcFilter());
        //stuff after
    }
}

または、WebActivatorをGlobalFilters.Filters持たないユーザーのためのコレクションとして、global.asax.csファイル内:

GlobalFilters.Filters.Add(new MyMvcFilter());

どちらの場合も、適切なFilterAttributeタイプから継承する必要がないことに注意してください。Web APIフィルターはSystem.Web.Http.IFilterインターフェイスを実装するだけで済みますが、MVCフィルター登録チェックは、クラスがSystem.Web.Mvc名前空間で定義された少数のフィルターインターフェイスの1つを確実に継承するようにします。


カスタムのWeb APIフィルターをwebapiconfig.csに追加するとうまくいきます。global.asax.csに追加したときに機能しなかった理由がわかりません
Tatipaka

@tatipakaに感謝します。webapiconfigへの追加が機能しました。
Gokulnath

12

MVC 4 RC以降、正しいクラス名はHttpFilterCollectionです。

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

protected void Application_Start()
{
    RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}

8

グローバルフィルターを使用する代わりに、私はこれを行うことを好みます:

[MyWebApiFilter]
public class CustomizedApiControllerBase : ApiController
{
   ...
}

その後、CustomizedApiControllerBase このアプローチからすべてのAPIコントローラーを継承します。このアプローチは、global.ascxファイルのグローバルフィルターと比較してより表現力があります。


System.Web.Http.Filters.ActionFilterAttributeを継承するFilterを作成し、必要なメソッドで直接使用するようにしました。機能するだけなので、登録する必要はありませんか?
joedotnot

@joedotnot特定のフィルターではなく、「グローバル」フィルターについてです。フィルター処理するメソッドを指定できる場合、アプローチは問題ありませんが、コントローラーアクションに関係なくフィルター処理する場合は、グローバルフィルターが必要です。
Mahmoud Moravej
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.