Friday, 6 September 2013

Simplifying your actions in asp.net mvc controllers with action filters.

Asp.net mvc, was to developed to be lean and mean and just understanding how it couples and work together is a prerequisite to writing great mvc application. Today i will try to throw more light on action filters in mvc.

If you ask Microsoft Mvc Team they will tell you that, An action filter is an attribute that you can apply to a controller action -- or an entire controller -- that modifies the way in which the action is executed. But if you ask me? well an action filter is just a place to keep and execute the code you do not want to be in your controller action method. And why will this be you may say, there are several reasons why you will like to create an action filter in mvc, some of these reasons are:
  1. It aides code reuse
  2. It minimizes cluttering of the action method.
  3. It provides an extra extension point to execute a certain piece of code in a specific time
Among others, when you look at this reflectively you will see that there so many reasons for which using action filters is a yes. Ok! enough i now get it, how can i implement it.

In Mvc there are various pre-packaged action filter attributes that modifies the behaviour of your action method in various ways. Some of the important ones are: 

AuthorizeAttribute: This action filter enables you to restrict the access of a particular action or controller to a predefined role(s).

HandleErrorAttribute: This filter handles any error that is raised whenever an action method is called.

OutputCacheAttribute: This filter caches the result of an action method execution for a specified amount of time.

Implementing a custom attribute

The Microsoft mvc team in other to aide developers in creating a custom attribute added one more attribute to be inherited from. This attribute ActionFilterAttribute implements IResultFilter and IActionFilter interfaces from the Filter class.

In this article we are going to create a custom attribute that checks if user email is unique, before executing the register function. We are going to call our custom attribute VerifyEmailAttribute but you can call yours anything you like. Here is the custom attribute code

 public class VerifyEmailAttribute : ActionFilterAttribute
    {
        //Create an interface for the account repository class
        //This will be solidified using IOC
        private readonly IAccountRepository _accountRepository;
 
        public VerifyEmailAttribute()
        {
            _accountRepository = new AccountRepository();
        }
 
        //We override this method because we wanted it to be 
        //called every time a specific action is about to execute
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            //Get the email submitted by the user
            string email = (string)actionContext.ActionArguments["Email"];
 
            if (email.IsNullOrWhiteSpace())
            {
                actionContext.ActionArguments["isEmailValid"] = false;
            }
            else
            {
                var isUnique = _accountRepository.IsEmailUnique(email);
 
                if (isUnique)
                {
                    actionContext.ActionArguments["IsEmailValid"] = true;
                }
                else
                {
                    actionContext.ActionArguments["IsEmailValid"] = false;
                }
            }
            base.OnActionExecuting(actionContext);
        }
    }

and here is our AddEmail action method decorated with attribute


 //Here is our custom verify email attribute.
        [VerifyEmail]
        public ActionResult AddEmail(string email, bool isEmailValid)
        {
            if (isEmailValid)
            {
                //Todo: Process the action method
                return View();
            }
           ModelState.AddModelError(" ", "Email already exists, add a new one.");
            return View(email);
        }

Now what this attribute really does is that it calls our account repository and check if the given email exists returning a bool to identify the result. In our VerifyEmailAttribute class we implemented one override-able method of the ActionFilterAttribute class. This method always executes before the action method it is decorated with or before all the action methods in a controller class if the attributes gets applied in the class level executes.

Action filters is one of the little goodness in mvc which eases application development, reduces cluttering and over indentation inside the action method.Using it had made may daily development easy and am sure it will do the same to you.

NB: Why don't you leave a comment telling me what you think of the article, so it can help me in writing better ones.

No comments:

Post a Comment