Custom Action Filters in MVC

Custom Action Filters in MVC

In this article, I am going to discuss how to create and use Custom Action Filters in MVC Application with one real-time application.

What are Action Filters in MVC?

An Action Filter in ASP.NET MVC Application is an attribute and can be applied either at the action methods of a controller or at the controller level directly. So, basically, action filters allow us to execute some custom code either before executing an action method or immediately an action method completes its execution

Why do we need Action Filters in MVC?

As we already discussed, Filters in MVC are used to execute some custom code or logic at different levels of request processing. The other advantage is that these Filters can be applied to multiple controllers or multiple action methods of different controllers which mean it allows us to share the custom code or logics across Controllers.

For example, let’s say we want to execute some security code or some request and response logging code across the controllers. Then we can write a custom filter containing all those logics and apply that filter wherever you want to execute these custom logic.

The following are some of the situations where you may use Filters.

  1. Creating a privileged authorization
  2. Logging the user request
  3. Pre-processing image upload
  4. Fetching data to display in the layout menu
  5. Localization of the application
  6. Reading browser user agent information to perform a particular task
  7. Caching, etc.
How to create Custom Action Filter in MVC?

In ASP.NET MVC application, we can create a custom action filter in two ways. They are as follows

  1. First, by implementing the IActionFilter interface and inheriting the FilterAttribute class.
  2. Second, by overriding the ActionFilterAttribute abstract class.

The IActionFilter interface includes the following methods to implement:

Custom Action Filters in MVC Application

The ActionFilterAttribute abstract class includes the following methods which need to be override:

MVC Custom Action Filters

So, you can use any of the above approaches to create a Custom Action Filter in MVC. Let’s understand when the above four methods are going to be executed.

OnActionExecuting(ActionExecutingContext filterContext)- This method is going to be execute before executing a controller action method.

OnActionExecuted(ActionExecutedContext filterContext)- This method is called after a controller action is executed.

OnResultExecuting(ResultExecutingContext filterContext)- This method is called before a controller action result is executed.

OnResultExecuted(ResultExecutedContext filterContext)- This method is called after a controller action result is executed.

Example:

Let us consider a scenario of Logging. For every incoming request, we need to log some data to the files on the basis of some logic. If we don’t create this logic inside a custom filter, then we will have to write the same logic for each controller’s action.

This mechanism will lead to two problems:

  1. Duplication of code; and
  2. Violation of the Single Responsibility Principles. That means action methods will now perform additional tasks of logging.

We can solve the above two problems by putting the logging logic inside a custom action filter and applying the filter at all the controllers’ level.

Creating a new ASP.NET MVC Application

Open visual studio and select File => New => Project from the context menu as shown in the below image.

Creating MVC Project

Once you click on the “Project” link, a new dialog will pop up. From that window, we are going to choose “Web” templates from the left pane. From the middle pane, we need to select “ASP.NET Web Application“. Then provide a meaningful name to the project such as “CustomActionFilter”. Finally, click on the “OK” button as shown in the below image

Selecting MVC Project

Once you click on the “OK” button a new dialog will pop up with the name “New ASP.NET Project” for selecting project Templates as shown in the below image.

Choosing Empty MVC Project Template

In this dialog, we are going to choose “Empty” and “MVC” project template with the Authentication type as “No Authentication” and then click on the “OK” button. Once you click on the OK button it will take some to time create the project for us.

Adding Log Folder:

Let’s add a folder called Log into the project’s root directory. To do so, just right-click on the “CustomActionFilter” project and then select Add ➜ “New Folder and name it as Log. In this folder, we are going to create a text file with the Log.txt where we will store the Log data.

Creating Custom Action Filter in MVC:

Create a class file with name LogFilter.cs within the Models folder and then copy and paste the following code in it.

using System.Web;
using System;
using System.Web.Mvc;
using System.IO;
using System.Web.Routing;

namespace CustomActionFilter.Models
{
    public class LogFilter : FilterAttribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            Log("OnActionExecuted", filterContext.RouteData);
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Log("OnActionExecuting", filterContext.RouteData);
        }

        private void Log(string methodName, RouteData routeData)
        {
            var controllerName = routeData.Values["controller"];
            var actionName = routeData.Values["action"];

            string message = methodName + " Controller:" + controllerName + " Action:" + actionName + " Date: "
                            + DateTime.Now.ToString() + Environment.NewLine;
            
            //saving the data in a text file called Log.txt
            File.AppendAllText(HttpContext.Current.Server.MapPath("~/Log/Log.txt"), message);
        }
    }
}

Here we use the first version of creating Custom Action Filter. That is by implementing the IActionFilter interface and inheriting from FilterAttribute class so that we can use this class as a Filter.

Using the Custom Action Filter in MVC:

Create a Controller with the name Home Controller and then copy and paste the following code in it.

using System.Web.Mvc;
using CustomActionFilter.Models;

namespace CustomActionFilter.Controllers
{
    [LogFilter]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Contact()
        {
            return View();
        }
    }
}

Creating the Index and Contact Views:

Index.cshtml

@{
    ViewBag.Title = "Index";
}
<h2>Index View</h2>

Contact.cshtml

@{
    ViewBag.Title = "Contact";
}
<h2>Contact View</h2>

Now run the application and see the text file.

Creating Custom Action Filter using ActionFilterAttribute:

Let us modify the LogFilter class as shown below override the ActionFilterAttribute.

using System.Web;
using System;
using System.Web.Mvc;
using System.IO;
using System.Web.Routing;

namespace CustomActionFilter.Models
{
    public class LogFilter : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            Log("OnActionExecuted", filterContext.RouteData);
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Log("OnActionExecuting", filterContext.RouteData);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            Log("OnResultExecuting", filterContext.RouteData);
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            Log("OnResultExecuted", filterContext.RouteData);
        }

        private void Log(string methodName, RouteData routeData)
        {
            var controllerName = routeData.Values["controller"];
            var actionName = routeData.Values["action"];

            string message = methodName + " Controller:" + controllerName + " Action:" + actionName + " Date: "
                            + DateTime.Now.ToString() + Environment.NewLine;
            
            //saving the data in a text file called Log.txt
            File.AppendAllText(HttpContext.Current.Server.MapPath("~/Log/Log.txt"), message);
        }
    }
}

As you can see, now the LogFilter class is derived from the ActionFilterAttribute abstract class and we also override all the methods. Now, it logs before and after the action method or result executes. You can apply Log attribute to any Controller or action methods where you want to log the action.

Run the application and open the Log.txt file which is inside Log Folder and checks the log that is generated by the Log Filter.

SUMMARY

In this article, I try to explain how to create and use the Custom Action Filters in MVC application with a simple example. I hope you understood how to create and consume Custom Action Filters in ASP.NET MVC application. 

Leave a Reply

Your email address will not be published. Required fields are marked *