Come aggiungere filtri ASP.Net Web Api globali?


98

Ho creato un filtro Web Api (utilizzando System.Web.Http.Filters.ActionFilterAttribute) ma non riesco a farlo funzionare all'interno di ASP.Net MVC 4. Ho provato ad aggiungerlo al RegisterGlobalFilters()metodo ma non ha funzionato.

Quindi, se si utilizza Web Api ospitata in ASP.Net MVC, come si registrano i filtri?

Risposte:


110

Il codice seguente, nel mio Global.asax, funziona per me:

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

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

6
Qualcuno può spiegare cosa sta succedendo qui? Perché ci sono due serie di filtri globali? Questo non fa di "Global" un ossimoro?
Luke Puplett,

6
Un set di filtri è per MVC e l'altro è per l'API Web. Sono due cose separate e normalmente non vorresti che i filtri per l'una fossero applicati all'altra.
Shane Courtrille

2
Il mio filtro WebApi viene chiamato due volte. Qualcuno ha questo problema?
Andrew Kalashnikov

87

nota che questa risposta è vera fino a MVC 5 / Web API 2

Risposta breve: i filtri MVC e API Web non sono compatibili tra loro e se si desidera registrarli a livello globale, è necessario utilizzare le classi di configurazione appropriate per ciascuno.

Risposta lunga: ASP.NET MVC e l'API Web sono appositamente progettati per funzionare in modo simile, ma in realtà sono creature diverse.

L'API Web risiede nello System.Web.Httpspazio dei nomi, mentre MVC risiede nello System.Web.Mvcspazio dei nomi. I due vivranno felicemente fianco a fianco, ma uno non contiene l'altro e nonostante le somiglianze nel modello di programmazione, le implementazioni sottostanti sono diverse. Proprio come i controller MVC ei controller API Web ereditano classi controller di base diverse (MVC è semplicemente denominato Controllere API Web è denominato ApiController) I filtri MVC ei filtri API Web ereditano da FilterAttributeclassi diverse (entrambi condividono lo stesso nome in questo caso, ma sono classi separate che vivono nei rispettivi spazi dei nomi).

I filtri globali dell'API Web vengono registrati tramite l' HttpConfigurationoggetto disponibile nel Registermetodo WebApiConfig.cs se stai utilizzando un modello di progetto con WebActivator:

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

o altrimenti in global.asax.cs:

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

I filtri globali Mvc vengono registrati tramite un GlobalFilterCollectionoggetto, disponibile tramite il RegisterGlobalFiltersmetodo FilterConfig.cs per i progetti che utilizzano WebActivator:

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

o nel file global.asax.cs a titolo di GlobalFilters.Filtersraccolta per chi non ha WebActivator:

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

Vale la pena notare che in entrambi i casi non è necessario ereditare dal FilterAttributetipo appropriato . I filtri API Web devono implementare solo l'interfaccia System.Web.Http.IFilter, mentre la registrazione del filtro MVC verifica che la tua classe erediti una delle poche interfacce di filtro definite nello System.Web.Mvcspazio dei nomi.


L'aggiunta di filtri API Web personalizzati in webapiconfig.cs funziona per me. Non capisco perché non ha funzionato quando è stato aggiunto in global.asax.cs
Tatipaka

grazie @tatipaka. l'aggiunta a webapiconfig ha funzionato.
Gokulnath

12

A partire da MVC 4 RC, il nome della classe corretto è HttpFilterCollection :

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

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

8

Invece di usare filtri globali preferisco fare questo:

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

E poi eredita tutti i controller API da CustomizedApiControllerBase Questo approccio è più espressivo rispetto ai filtri globali nel file global.ascx.


Ho creato un Filtro ereditando da System.Web.Http.Filters.ActionFilterAttribute e ho proceduto ad utilizzarlo direttamente sui metodi che lo richiedo. Funziona e basta, quindi perché non devo registrarlo?
gioedotnot

@joedotnot Si tratta di filtri "globali" non di quelli specifici. Se è possibile specificare quale metodo si desidera filtrare, l'approccio è corretto, ma quando si desidera filtrare indipendentemente dalle azioni del controller, sono necessari filtri globali.
Mahmoud Moravej
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.