2013-02-20 19 views
10

Ich verwende MVC 4 Web API, um eine Service-Schicht für eine Anwendung zu erstellen. Ich versuche, einen globalen Filter zu erstellen, der auf alle eingehenden Anfragen an die API wirkt. Jetzt verstehe ich, dass dies anders als Standard-MVC Global Action Filter konfiguriert werden muss. Aber ich habe Probleme, eines der Beispiele, die ich online finde, zu funktionieren.MVC 4 Web API-Register-Filter

Das Problem, in das ich hineingeraten bin, ist die Registrierung des Filters mit Web-API.

Ich habe meine Global.asax wie diese aufgebaut ...

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); 
    } 
} 

Meine Standard-Mvc-Routing und Filter korrekt funktionieren. Ebenso wie mein WebApi-Routing. Hier ist, was ich für meine WebAPI Filter Registrierung haben ...

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

Und hier ist der 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 
    } 
} 

Dieser Filter funktioniert gut, wenn es mit dem Standard-Mvc GlobalFilterCollection registriert ist, aber Wenn ich versuche, es mit System.Web.Http.Filters.HttpFilterCollection zu registrieren, erhalte ich die Fehlermeldung, dass es dem Parametertyp System.Web.Http.Filters.IFilter nicht zuweisbar ist.

Also nehme ich an, dass mein PerformanceTestFilter von etwas anderem als ActionFilterAttribute erben muss, um als Webapi-Filter registriert zu werden. Ich bin mir nicht sicher, was das sein muss.

Ich kann mir vorstellen, dass ich zwei individuelle Filter erstellen muss, um mit mvc bzw. webapi zu arbeiten. Wenn es einen Weg gibt, einen Filter zu erstellen, der für beide registriert werden könnte, wäre das großartig. Aber mein Hauptanliegen ist einfach, es für webapi arbeiten zu lassen.

Dank

Antwort

10

Folgendes sollte funktionieren. Wir verwenden das für unser Web-API-Projekt.

GlobalConfiguration.Configuration.Filters ist vom Typ HttpFilterCollection

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

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

Auch, wenn Sie in einem Projekt arbeiten, das sowohl MVC und WebAPI assembilies enthält, können Sie überprüfen, was der Namespace ist Ihr Actionnamespace. Es ist ziemlich verwirrend denn es sind zwei ActionFilterAttributes sowohl unter:

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

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

Es scheint, dass Sie zwei Filter haben müssen, eine für API und eine für MVC. Sie können den allgemeinen Code in eine separate Klasse einteilen und dann einfach den spezifischen Filter verwenden, um zu Ihrer gemeinsamen Klasse aufzurufen, wodurch DRY nicht verletzt wird und im Wesentlichen die eigentlichen Filter als Wrapper verwendet werden, die als Filter registriert werden können.

+3

Ok, diese Lösung erlaubt mein Projekt zu erstellen und ich habe meinen Filter sowohl für "System.Web.Http.Filters.HttpFilterCollection" für die Web-API als auch "GlobalFilterCollection" für Standard-MVC-Action-Filtering registriert. Wenn ich jedoch zu einer der API-Methoden navigiere, wird der Filter nicht ausgeführt. Der Filter funktioniert für die Standard-MVC-Controller-Aktionen, nicht jedoch für die Web-API-Methoden. Irgendwelche Vorschläge? – jdavis

+0

Stellen Sie eine neue Frage.Stellen Sie keine neuen Fragen in Kommentaren. –

+1

@Sam, Warum löschen Sie die Filtersammlung, bevor Sie Ihre eigene hinzufügen? – Vegar