Web API Filters


Web API Filters

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.
Filters are actually attributes that can be applied on the Web API controller or one or more action methods. Every filter attribute class must implement IFilter interface included in System.Web.Http.Filters namespace. However, System.Web.Http.Filters includes other interfaces and classes that can be used to create filter for specific purpose.
The following table lists important interfaces and classes that can be used to create Web API filters.
Filter TypeInterfaceClassDescription
Simple FilterIFilter-Defines the methods that are used in a filter
Action FilterIActionFilterActionFilterAttributeUsed to add extra logic before or after action methods execute.
Authentication FilterIAuthenticationFilter-Used to force users or clients to be authenticated before action methods execute.
Authorization FilterIAuthorizationFilterAuthorizationFilterAttributeUsed to restrict access to action methods to specific users or groups.
Exception FilterIExceptionFilterExceptionFilterAttributeUsed to handle all unhandled exception in Web API.
Override FilterIOverrideFilter-Used to customize the behaviour of other filter for individual action method.
As you can see, the above table includes class as well as interface for some of the filter types. Interfaces include methods that must be implemented in your custom attribute class whereas filter class has already implemented necessary interfaces and provides virtual methods, so that they can be overridden to add extra logic. For example, ActionFilterAttribute class includes methods that can be overridden. We just need to override methods which we are interested in, whereas if you use IActionFilter attribute than you must implement all the methods.
Visit MSDN to know all the classes and interfaces available in System.Web.Http.Filters.
Let's create simple LogAttribute class for logging purpose to demonstrate action filter.
First, create a LogAttribute class derived from ActionFilterAttribute class as shown below.
Example: Web API Filter Class
public class LogAttribute : ActionFilterAttribute 
 {
    public LogAttribute()
    {

    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        Trace.WriteLine(string.Format("Action Method {0} executing at {1}", actionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        Trace.WriteLine(string.Format("Action Method {0} executed at {1}", actionExecutedContext.ActionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");
    }
}
In the above example, LogAttribute is derived from ActionFilterAttribute class and overrided OnActionExecuting and OnActionExecuted methods to log in the trace listeners. (You can use your own logging class to log in textfile or other medium.)
Another way of creating LogAttribute class is by implementing IActionFilter interface and deriving Attribute class as shown below.
Example: Web API Filter Class
public class LogAttribute : Attribute, IActionFilter
{
    public LogAttribute()
    {

    }

    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        Trace.WriteLine(string.Format("Action Method {0} executing at {1}", actionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");

        var result = continuation();

        result.Wait();
            
        Trace.WriteLine(string.Format("Action Method {0} executed at {1}", actionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");

        return result;
    }

    public bool AllowMultiple
    {
        get { return true; }
    }
} 
In the above example, deriving from Attribute class makes it an attribute and implementing IActionFilter makes LogAttribute class as action filter. So now, you can apply [Log] attributes on controllers or action methods as shown below.
Example: Apply Web API Filter on Controller
[Log]
public class StudentController : ApiController
{
    public StudentController()
    {
            
    }

    public Student Get()
    {
        //provide implementation  
    }
}
So now, it will log all the requests handled by above StudentController. Thus you can create filters for cross-cutting concerns.

No comments:

Post a Comment