63

I'm new to the whole MVC thing and am looking at re-implementing some WCF services using ASP.NET Web API. As part of that, I'd like to implement an action filter that logs all actions and exceptions as well as does timing so I thought I'd start with an Action Filter, however the filter is not being invoked.

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

and on the controller, I have

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

The routes are setup in Global.asax using calls like:

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

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

The issue is that the actions on the MyResourceController are invoked as expected and run successfully. The client is able to query the server for the necessary info and all behaves fine, except that none of the action filter methods are ever invoked.

My understanding was that the rest happened "automagically". That's clearly not enough - Any sugestions as to what is wrong? Do I need to register these somewhere?

3
  • NOTE: I've tried adding the attribute to both the operation as well as the class and neither way worked. Commented Apr 24, 2012 at 23:43
  • BE 100% sure your API Controller related classes uses the ActionFilter from System.Web.HttpFilters and NOT the one from System.Web.Mvc Commented Apr 25, 2012 at 0:05
  • At the top you should see something like: using System.Web.HttpFilters; Commented Apr 25, 2012 at 0:05

2 Answers 2

192

You have to be sure your code uses the ActionFilterAttribute from the System.Web.Http.Filters namespace and not the one from System.Web.Mvc.

So please check that you have

 using System.Web.Http.Filters;
Sign up to request clarification or add additional context in comments.

2 Comments

For those wondering, use System.Web.Mvc if you are building Mvc application and use System.Web.Http.Filters if you are building Web Api (controller inherited from ApiController)
If this is in an assembly you need to include the Microsoft.AspNet.WebApi.Core NuGet package
4

As Sander mentioned I tried the below code, its action filter is getting executed.

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 is a static string list. if you want to check whether OnActionExecuted is getting executed or not, you may call the same API method again, you would see the "OnActionExecuted" in the Messages list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.