2013-02-20 23 views
10

Sto utilizzando MVC 4 Web API per creare un livello di servizio per un'applicazione. Sto cercando di creare un filtro globale che agirà su tutte le richieste in arrivo all'API. Ora capisco che questo deve essere configurato in modo diverso rispetto ai filtri di azione globali MVC standard. Ma sto avendo problemi nel trovare qualcuno degli esempi che sto trovando online per funzionare.MVC 4 Filtro registro API Web

Il problema che sto incontrando è nella registrazione del filtro con Web API.

Ho il mio Global.asax istituito come questo ...

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     MVCConfig.RegisterRoutes(RouteTable.Routes); 
     MVCConfig.RegisterGlobalFilters(GlobalFilters.Filters); 

     WebApiConfig.RegisterRoutes(GlobalConfiguration.Configuration); 
     WebApiConfig.RegisterGlobalFilters(GlobalConfiguration.Configuration.Filters); 
    } 
} 

mio instradamento e filtri MVC di serie funzionano correttamente. Come il mio routing WebApi. Ecco quello che ho per la mia iscrizione filtro WebAPI ...

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

Ed ecco il PerformanceTestFilter ...

public class PerformanceTestFilter : ActionFilterAttribute 
{ 
    private readonly Stopwatch _stopWatch = new Stopwatch(); 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     _stopWatch.Reset(); 
     _stopWatch.Start(); 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     _stopWatch.Stop(); 
     var executionTime = _stopWatch.ElapsedMilliseconds; 
     // Do something with the executionTime 
    } 
} 

Questo filtro funziona bene quando si è registrato con il MVC GlobalFilterCollection standard, ma quando provo a registrarlo con System.Web.Http.Filters.HttpFilterCollection ottengo un errore che dice che non è assegnabile al tipo di parametro System.Web.Http.Filters.IFilter.

Quindi presumo che il mio PerformanceTestFilter debba ereditare da qualcosa di diverso da ActionFilterAttribute per poter essere registrato come filtro webapi. Non sono sicuro di cosa debba essere.

Immagino di dover creare due filtri singoli per lavorare rispettivamente con mvc e webapi. Se esiste un modo per creare un filtro che possa essere registrato su entrambi, sarebbe fantastico. Ma la mia preoccupazione principale è semplicemente quella di farlo funzionare per webapi.

Grazie

risposta

10

Di seguito dovrebbe funzionare. In realtà lo usiamo per il nostro progetto di API web.

GlobalConfiguration.Configuration.Filters è di tipo HttpFilterCollection

var filters = System.Web.Http.GlobalConfiguration.Configuration.Filters; 
filters.Clear(); 
filters.Add(new ValidationActionFilterAttribute()); 

public class ValidationActionFilterAttribute : FilterAttribute, IActionFilter, IFilter 
{ 
    ... 
} 

Inoltre, se si lavora in un progetto che contiene sia MVC e assembilies WebAPI, si potrebbe verificare qual è lo spazio dei nomi tuo spazio dei nomi di ActionFilterAttribute. E 'causa abbastanza confusione ci sono due ActionFilterAttributes sotto entrambi:

System.Web.Http.Filters 
    System.Web.Http.Mvc 

Fonte: Why is my ASP.NET Web API ActionFilterAttribute OnActionExecuting not firing?

Sembra che sarà necessario avere due filtri, uno per API e uno per MVC. È possibile calcolare il codice comune in una classe separata, quindi utilizzare semplicemente il filtro specifico per chiamare la classe comune, non violando pertanto DRY e utilizzando essenzialmente i filtri effettivi come wrapper che possono essere registrati come filtri.

+3

Ok, questa soluzione ha consentito la creazione del mio progetto e il mio filtro è stato registrato sia per "System.Web.Http.Filters.HttpFilterCollection" per l'API Web sia per "GlobalFilterCollection" per il filtro di azione MVC standard. Tuttavia, quando si accede a uno dei metodi API, il filtro non viene eseguito. Il filtro funziona per le azioni del controller MVC standard, ma non per i metodi dell'API Web. Eventuali suggerimenti? – jdavis

+0

Fai una nuova domanda.Non fare nuove domande nei commenti. –

+1

@ Sam, perché si elimina la raccolta di filtri prima di aggiungerne di propri? – Vegar

Problemi correlati