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?
Web API includes filters to add extra logic before or after action method executes. Filters can be used to provide cross-cutting features such as logging, exception handling, performance measurement, authentication and authorization.
You can create custom filter attributes by implementing an appropriate filter interface for which you want to create a custom filter and derive the FilterAttribute class to use that class as an attribute. For example, implement IExceptionFilter and the FilterAttribute class to create a custom exception filter.
To apply the filter to all Web API controllers, add it to GlobalConfiguration. Filters. public static class WebApiConfig { public static void Register(HttpConfiguration config) { config. Filters.
In order to make it easier for you to implement a custom action filter, the ASP.NET MVC framework includes a base ActionFilterAttribute class. This class implements both the IActionFilter and IResultFilter interfaces and inherits from the Filter class.
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With