Filter Overrides in MVC

Filter Overrides in ASP.NET MVC

ASP.NET MVC 5 and ASP.NET Web API 2 added a very important feature called Filter Overrides. A good definition of filter overrides is available in release notes, “You can now override which filters apply to a given action method or controller, by specifying an override filter. Override filters specify a set of filter types that should not run for a given scope (action or controller). This allows you to add global filters, but then exclude some from specific actions or controllers”.

Let’s simplify this definition, ASP.NET MVC 5 has introduced a new feature called Filter Override, which allows us to clear or hide certain Filters created in a higher scope. For example, if we created a global action filter then they are applicable to all controllers or if we apply the filter at controller level then they are applicable to all actions of that controller, but we could override those filters on a case by case basis at the controller action level. This allows us to set global or controller filters that apply almost all cases and just override them in few, specific places where those filters don’t apply.

In this article, I am going to discuss the problem that filter overrides is trying to solve with an example. I will also show you a bug in MVC 5 regarding filter overrides and how to solve that bugs in MVC 5.

As we know there are the following five types of filters available with MVC:
  1. Authentication filters
  2. Authorization filters
  3. Action filters
  4. Result filters
  5. Exception filters
So we have five type filter overrides corresponding to this:
  1. OverrideAuthenticationAttribute
  2. OverrideAuthorizationAttribute
  3. OverrideActionFiltersAttribute
  4. OverrideResultAttribute
  5. OverrideExceptionAttribute

We can mark any action method with an override filter attribute that essentially clears all filters in an upper scope (in other words controller level or global level).

Let’s understand this with an example, if we created a controller-level action filter or global action filter, now I have an action method on which I do not want to action filter. In this case, the Filter Override feature is very useful.

Create New Asp.Net MVC Application

From the Visual Studio, Start page click on New Project link.

Filter Overrides in ASP.NET MVC

After clicking on “New Project” link a new dialog will pop up.

In that we are going to select web templates from the left pane after selecting web template, we find only one project template in it “ASP.NET Web Application” just select that.

Filter Overrides in ASP.NET MVC

After selecting this project template next we are going to name the project as FilterOverrideinMVC and clicking on the OK button a new dialog will pop up with Name New ASP.NET Project for selecting project Templates.

Filter Overrides in ASP.NET MVC

In this dialog, we are going to choose MVC project template and then we are going to choose Authentication type for doing that just click on Change Authentication button, a new dialog will pop up with the name “Change Authentication” here we are going to choose Individual User Accounts. Then click on OK button as shown below.

Filter Overrides in ASP.NET MVC

Note: – Individual User Accounts

If you choose this option for Authentication of application then your application will be configured to use ASP.NET identity [ASP.NET Membership] where User register in the application and then sign in using credentials and also User sign in via social accounts such as Facebook, Twitter, Google, Microsoft and other providers. All user data will be stored in the SQL server database.

After selecting Authentication type as Individual User Accounts click on OK Button.

After creating the project it will show the folder structure as shown below.

Filter Overrides in ASP.NET MVC

After creating project first thing we are going add Filter folder in Project.

For adding Folder just right-click on “FilterOverrideinMVC” and then select Add and inside that select “New Folder” then rename the folder name as Filters as shown below.

Filter Overrides in ASP.NET MVC

After adding Filter folder the next thing we are going add Filters in this folder to validate User is Logged in to the application or not.

Adding Authentication Filter

We are going to add Filter in filters folder with name CustomAuthenticationFilter and this filter will inherit a class FilterAttribute and IAuthenticationFilter, and in this filter we are just going to check Session is IsNullOrEmpty if it is NULL or Empty then we are going to redirect it to Error View else if it is not NULL or Empty then it will allow executing Action Method.

Right click on Filters folder and Click on Add => Class, then provide the class name as “CustomAuthenticationFilter” and click on Add as shown below

Filter Overrides in ASP.NET MVC

Copy and paste the below code in CustomAuthenticationFilter class

using System.Web.Mvc;
using System.Web.Mvc.Filters;

namespace FilterOverrideinMVC.Filters
{
    public class CustomAuthenticationFilter : FilterAttribute, IAuthenticationFilter
    {
        public void OnAuthentication(AuthenticationContext filterContext)
        {
            if (string.IsNullOrEmpty(Convert.ToString(filterContext.HttpContext.Session["UserID"])))
            {
                filterContext.Result = new ViewResult
                {
                    ViewName = "Error"
                };
            }
        }

        public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
        {
        }
    }
}

In next step we are going to apply CustomAuthenticationFilter Filter on HomeController, this Controller is created by default when we have created the project.

Filter Overrides in ASP.NET MVC

In this step, we are going to apply CustomAuthenticationFilter Filter to Home controller after applying this filter.

Applying CustomAuthenticationFilter Filter on HomeController

The User who is going to access this controller must have Session[“UserID”] if it is NULL or empty then it is going to redirect it to Error View.

namespace FilterOverrideinMVC.Controllers
{
    [CustomAuthenticationFilter]  //Applied Custom Authentication Filter
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}

Now let’s Save and Run this Project and access URL:- http://localhost:####/Home/Index

It will redirect it to Error View as shown below.

Filter Overrides in ASP.NET MVC

Meanwhile, if we are going to access URL: – http://localhost:xxxx/Home/About

It will redirect it to the Error View as shown below.

Filter Overrides in ASP.NET MVC

Meanwhile, if we are going to access URL: – http://localhost:3025/Home/Contact

It will redirect it to the Error View as shown below.

Filter Overrides in ASP.NET MVC

Applying OverrideAuthentication Filter on About Action Method

In this part we are going to apply [OverrideAuthentication] filter on About Action Method.

namespace FilterOverrideinMVC.Controllers
{
    [CustomAuthenticationFilter]  //Applied Custom Authentication Filter
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OverrideAuthentication]  //Applied override Authentication Filter       
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}
Scenario 1:- 

If we are going to access Index Action Method still it is going to redirect to Error View because CustomAuthenticationFilter is applied on Controller it means it is applied to all Action Methods inside that Controller.

Scenario 2:- 

If we are going to access Contact Action Method still it is going to redirect to Error View because CustomAuthenticationFilter is applied on Controller it means it is applied to all Action Methods inside that Controller.

Scenario 3:- 

Now we are going to access About Action Method it still redirect to Error View after applying [OverrideAuthentication] Filter on this Action Method,

Actually, this is a bug in ASP.NET MVC 5 with Filter Overrides that has been fixed in the ASP.NET MVC 5.1 Preview. To get this to work in my example, I created my own [OverrideAuthorization] Attribute that implements IOverrideFilter, etc. As shown below

Right click on Filters folder and add a class file with name OverrideAuthenticationFilter and copy and paste the below code

using System.Web.Mvc;
using System.Web.Mvc.Filters;

namespace FilterOverrideinMVC.Filters
{
    public class OverrideAuthenticationFilter : FilterAttribute, IOverrideFilter
    {
        public Type FiltersToOverride
        {
            get
            {
                return typeof(IAuthenticationFilter);
            }
        }
    }
}
Now apply this filter to our About method of Home controller as shown below
namespace FilterOverrideinMVC.Controllers
{
    [CustomAuthenticationFilter]  //Applied Custom Authentication Filter
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        //[OverrideAuthentication] // Applied Override Authentication Filter will not work in MVC 5
        [OverrideAuthenticationFilter] //Customizing Override Authentication Filter to work in MVC 5
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}

Now let’s Save and Run this Project and access URL: – http://localhost:####/Home/About

It will redirect show the About View as shown below.

Filter Overrides in ASP.NET MVC

Note: – if we want to override Authentication filter then must only apply [OverrideAuthentication] filter but if we apply other filter such [OverrideAuthorization] or [OverrideActionFilters] or [OverrideResultFilters] or [OverrideExceptionFilters] will not work on it.

Adding Authorization Filter

We are going to add Filter in filter folder with name CustomAuthorizationFilter and this filter will inherit a class FilterAttribute and IAuthorizationFilter Interface, and in this filter we are just going to check Session is IsNullOrEmpty if it is NULL or Empty then we are going to redirect it to Error View else if it is not NULL or Empty then it will allow executing Action Method.

First Right click on Filters folder then select Add => Class and provide the class name as CustomAuthorizationFilter and click on add button as shown below

Filter Overrides in ASP.NET MVC

Copy and paste the below code
using System.Web.Mvc;

namespace FilterOverrideinMVC.Filters
{
    public class CustomAuthorizationFilter : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (string.IsNullOrEmpty(Convert.ToString(filterContext.HttpContext.Session["UserID"])))
            {
                filterContext.Result = new ViewResult
                {
                    ViewName = "Error"
                };
            }
        }
    }
}

In next step we are going to apply CustomAuthorizationFilter Filter on HomeController, this Controller is created by default when we have created project.

namespace FilterOverrideinMVC.Controllers
{
    [CustomAuthorizationFilter] //Applied custom Authorization Filter
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OverrideAuthorization] //Applied override Authorization
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}
Scenario1:- 

If we are going to access Index Action Method it is going to redirect to Error View because CustomAuthorizationFilter is applied on Controller it means it is applied to all Action Methods inside that Controller.

Scenario2:- 

If we are going to access Contact Action Method it is going to redirect to Error View because CustomAuthorizationFilter is applied on Controller it means it is applied to all Action Methods inside that Controller.

Scenario3:- 

Now we are going to access About Action Method it is still redirected to Error after applying the OverrideAuthentication Filter in About Action method.

Actually, this is a bug in ASP.NET MVC 5 with Filter Overrides that has been fixed in the ASP.NET MVC 5.1 Preview. To get this to work this example, we need to create custom [OverrideAuthorization] Attribute that implements IOverrideFilter, etc. As shown below

Right click on Filters folder and add a class file with name OverrideAuthenticationFilter and copy and paste the below code

namespace FilterOverrideinMVC.Filters
{
    public class OverrideAuthorizationFilter : FilterAttribute, IOverrideFilter
    {
        public Type FiltersToOverride
        {
            get
            {
                return typeof(IAuthorizationFilter);
            }
        }
    }
}
Now apply this filter to our About method of Home controller as shown below
namespace FilterOverrideinMVC.Controllers
{
    [CustomAuthorizationFilter] //Applied custom Authorization Filter
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        // [OverrideAuthorization] //Applied override Authorization will not work in MVC 5
        [OverrideAuthorizationFilter] //Customizing Override Authorization Filter to work in MVC 5
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page."
            return View();
        }
    }
}

Now let’s Save and Run this Project and access URL: – http://localhost:####/home/About

It will redirect show the About View as shown below.

Filter Overrides in ASP.NET MVC

Note: In the same way we can override Action filter, Exception Filter, and Result Filter.

Note: The Override does not work properly with MVC version 5.0 due to some internal bug. This bug was resolved in MVC version 5.1 (preview).

SUMMARY:
The Filter Overrides in ASP.NET MVC 5 are very useful when we are implementing a global or controller level filter and we do not want to apply an action filter on some Action methods in the controller. This feature is useful for removing the headache of applying filters for each and every action where we need to exclude only a few actions.

Leave a Reply

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