ASP.NET Web API ActionFilter example

2019-01-10 21:58发布

问题:

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?

回答1:

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;


回答2:

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.