Custom Action Filter in ASP.NET MVC

In MVC, filters play a very important role. Filters are used to inject an extra logic into the MVC request processing. Typically in an MVC application, we make use of filters to define logic which is used to apply add-on functionality to the application e.g. defining authorization, caching etc. In MVC, developers are provided with the following basic filters:

· Authorization
  • Implements IAuthorizationFilter interface.
  • Provides AuthorizeAttribute as the default class implementation.
  • Executes before any other filter or the action method.
· Action:
  • Implements IActionFilter.
  • Provides ActionFilterAttribute as the default class implementation.
  • Executes before and after the action method.
· Result:
  • Implements IResultFilter interface.
  • Executes before and after action result is executed.
· Exception:
  • Implements IExceptionFilter interface.
  • Provides HandleErrorAttribute as the default class implementation.
  • Executes only if exception is thrown by action method or an action result.
Filters are applied on the controller and/or action methods as an attribute. So for MVC application development, we can think to use attributes for Log entries in database, custom username password validations through the external WCF or web services.

In this article, we will see how to implement the Custom Exception Filter in MVC.  An assumption for this article is that the Model layer is creating using ADO.NET EF. The article demonstrates a custom exception filter used for ‘UpdateException’.

Some to-do’s before using the code:
  • Create MVC 3 application using VS2010.
  • Add the model layer in the application using ADO.NET EF.
  • Generate Controller and implement logic for performing Index, Create, Edit and Delete actions.
  • Run and test the functionality.
  • Create a Company Database in SQL Server with Department table.
Step 1: In the project, add a new folder, name it as ‘CustomFilterRepository’. Add a new class file in this folder, name it as ‘ModelExceptionAttribute.cs’. Add the following code in the class file:

using System.Data;
using System.Web.Mvc;
using MVC3_CustomException_Filter.Models;

namespace MVC3_CustomException_Filter.CustomFilterRepository
{
    /// <summary>
    /// Class used to Handle the Exception for 
    /// Duplicate Entry For Primary Key
    /// This Handles System.Data.UpdateException
    /// </summary>


    public  class ModelExceptionAttribute : FilterAttribute,IExceptionFilter
    {
        public  void OnException(ExceptionContext filterContext)
        {
            if (!filterContext.ExceptionHandled && 
            filterContext.Exception is UpdateException)
            {
                var routeData = filterContext.RouteData;
                var controllerName =  routeData.Values["controller"].ToString();
                var actionName = routeData.Values["action"].ToString() ;


                filterContext.Result = new RedirectResult("~/ErrorPages/"
                + controllerName + "_" + actionName + ".html");



                filterContext.ExceptionHandled = true;            }
        }

    }
}

The class ‘ModelExceptionAttribute’ is inherited from ‘FilterAttribute’ abstract class and implements the ‘IExceptionFilter’ interface. This interface provides method for exception filter. The method ‘OnException’ accepts ‘ExceptionContext’ object. This class provides exception context for Handling error. The code checks for the ‘UpdateException’. The result property of the ‘ExceptionContext’ class redirects to the Html page.

Step 2: Add a new Folder in the project and name it as ‘ErrorPages’. In this folder, add html pages with a name format like ‘ControllerName_ActionName.html’, e.g. for the Create action method of controller class, the html page will be ‘Department_Create.html’.

Note: You can go for another approach as per your application needs. Design the html page as per your requirement.

Step 3: In the department controller class, on the Create action, apply the custom filter as shown below:


[ModelException]
public ActionResult Create(Department department){
    try
    {
        if (ModelState.IsValid)
        {
  //your code here
           return RedirectToAction("Index");

        }


    }
    catch (Exception)
    {
        throw; 
    }


   return View(department);
}

Step 4: Run the application and navigate to the create action of the department controller class. Try to re-add the primary key value for the department number (DeptNo). An update exception will occur:


MVC3-Custom_Filter_UpdateException

Press F5 and an html page will appear as shown below:

Re1
Conclusion:

Using Custom filters in MVC 3, you can easily incorporate custom, value added business logic e.g. Custom Security, Custom Exception, Custom Logging in your application which makes your application more flexible and maintainable.

Download the entire source code




About The Author

Mahesh Sabnis is a Microsoft MVP having over 18 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). He also blogs regularly at DotNetCurry.com. Follow him on twitter @maheshdotnet

2 comments:

erichgibson said...

You made some decent points there. I looked on the internet for the issue and found most individuals will go along with with your website.

elliottweber said...

An impressive share, I just given this onto a colleague who was doing a little analysis on this. And he in fact bought me breakfast because I found it for him.. smile. So let me reword that: Thnx for the treat! But yeah Thnkx for spending the time to discuss this, I feel strongly about it and love reading more on this topic. If possible, as you become expertise, would you mind updating your blog with more details? It is highly helpful for me. Big thumb up for this blog post!