2012-04-24 17 views
48

Ich bin neu in der ganzen MVC-Sache und betrachte die Re-Implementierung einiger WCF-Dienste mit ASP.NET Web API. Als Teil davon würde ich gerne einen Aktionsfilter implementieren, der alle Aktionen und Ausnahmen protokolliert sowie das Timing, so dass ich dachte, ich würde mit einem Aktionsfilter beginnen, der Filter wird jedoch nicht aufgerufen.ASP.NET-Web-API ActionFilter-Beispiel

public class MyTrackingActionFilter : ActionFilterAttribute, IExceptionFilter 
{ 
    private Stopwatch stopwatch = new Stopwatch(); 

    public void OnException(ExceptionContext filterContext) 
    { 
      ... 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
      ... 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     this.stopwatch.Start(); 
     Trace.TraceInformation(" Entering {0}", filterContext.RouteData); 
    } 

}

und auf dem Controller, ich habe

[MyTrackingActionFilter] 
public class MyResourceController : ApiController 
{ 
    ... 
} 

Die Routen-Setup in Global.asax verwenden Anrufe wie:

var routeTemplate = ... 
var defaults = new { controller = controllerName, action = methodName }; 
var constraints = new { httpMethod = new HttpMethodConstraint(myHTTPMethods.Split(',')) }; 

routes.MapHttpRoute(methodName, routeTemplate, defaults, constraints); 

Das Problem ist, dass die Aktionen auf dem MyResourceController werden wie erwartet aufgerufen und erfolgreich ausgeführt. Der Client kann den Server nach den erforderlichen Informationen abfragen, und alles verhält sich gut, außer dass keine der Aktionsfiltermethoden jemals aufgerufen wird.

Mein Verständnis war, dass der Rest "automatisch" passiert ist. Das ist eindeutig nicht genug - Irgendwelche Vorschläge, was falsch ist? Muss ich diese irgendwo registrieren?

+0

HINWEIS: Ich habe versucht, das Attribut sowohl der Operation als auch der Klasse hinzuzufügen und keine der beiden Möglichkeiten. – WildeButNotOscar

+0

BE 100% sicher sein, dass die mit API Controller verbundenen Klassen den ActionFilter von System.Web.HttpFilters verwenden und NICHT den von System.Web.Mvc –

+0

. Oben sollten Sie etwas sehen wie: using System.Web.HttpFilters; –

Antwort

169

Sie müssen sicher sein, Ihr Code die Action vom System.Web.Http.Filters Namespace verwendet und nicht derjenige von System.Web.Mvc.

So überprüfen Sie bitte, dass Sie

using System.Web.Http.Filters; 
+0

Ich suche nach allen Anfragen und analysiere sie? ist diese Frage und diese Antwort auf mein Bedürfnis? Falls ja? Wie ? kann ich das machen? –

+1

@sabertabatabaeeyazdi Sie können einen Aktionsfilter für die Protokollierung verwenden – dotnetguy

+0

Für diejenigen, die sich wundern, verwenden Sie System.Web.Mvc, wenn Sie Mvc-Anwendung erstellen und System.Web.Http.Filters verwenden, wenn Sie Web-API (Controller von ApiController geerbt) erstellen – suhendri

0

haben Wie Sander erwähnte ich den Code unten versucht, seine Action-Filter wird immer ausgeführt.

public class WebAPIActionFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute 
{ 
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     PersonController.Messages.Add("OnActionExecuted"); 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     PersonController.Messages.Add("OnActionExecuting"); 
    } 
} 

public class WebAPIExceptionFilter : System.Web.Http.Filters.ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext actionExecutedContext) 
    { 
     PersonController.Messages.Add("OnException"); 
     actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.NotFound) { Content = new StringContent("Something went wrong") }; 
    } 
} 

PersonController.Messages ist eine statische String-Liste. Wenn Sie überprüfen möchten, ob OnActionExecuted ausgeführt wird oder nicht, können Sie dieselbe API-Methode erneut aufrufen. In der Nachrichtenliste wird "OnActionExecuted" angezeigt.