MVC Life Cycle - Part Six

Before reading this article, I highly recommend you read the previous parts of the article series:

However, I do recommend to refer the previous articles of MVC Life Cycle series. This will help you a ton in understanding the concepts at its core. Here, in this case we will see Filters in action. Therefore, before the action method chosen, the Authentication and Authorization filter runs. Filters are nothing but MVC components to inject extra logic in between the MVC pipeline.Therefore, first authentication filter runs and if it succeeds then it will go to Authorization filter otherwise it will again ask user to re-authenticate. However, authorization is the filter which says are you allowed to access particular thing or not.

At this stage, all authentication and authorization got succeeded which means, it will move to next step of pipeline wherein action invoker will pick the method to execute, but before execution it needs to populate data for Model Binding. Model Binding is the process of taking data from different data sources say Form Data, Query-String etc and create objects for action method parameters. Once, the parameters get populated then another set of action filters get executed which is associated with controllers itself like OnActionExecuting or OnActionExecuted. Therefore, before actual method gets invoked OnActionExecuting filter will run and after that the later one. After this entire exercise, Action Method will finally get called. Now, Action Methods after running will return Action Results. Now, there are variety of Action Results like JSON-Result, View Result, etc. Also, based on this Action Result it will generate the actual HTTP-Response for the HTTP-Request. This is just the brief snapshot around the Action Execution.

Therefore ActionInvoker is basically responsible for generating response. Again like many other MVC components, ActionInvoker also implements IActionInvoker which has only one method InvokeAction. However, you can also extend the same and create your own ActionInvoker which handles the request in custom way. But, as I mentioned earlier ASP.NET MVC is really powerful framework where in all the concerns are already addressed. So, I don't see any reason for doing this. Now, let us talk about Model Binders in detail. Model Binders fetch data from Value Providers. Below, I have mentioned the list of the same.
  • Query-Strings
  • Form-Data
  • Route-Data
  • It could be any custom source as well
Model Binders are also implemented via IModelBinder interface. This Interface also implements one method called BindModel. As we know that Model Binders run in between different filters. Hence, it would be good idea to talk about filters in detail.

Types of Filters: (Mentioned in execution order),

Types of Filters Mentioned in execution order
Authentication Filter IAuthenticationFilter
Authorization Filter IAuthorizationFilter
Action Filter IActionFilter
Result Filter IResultFilter
Exception Filter IExceptionFilter

Also, it is important to understand that filters can be applied at different levels. We can apply filters @Controller Method level or Controller level or Application level. This is why filters are really important component of MVC. We usually use filters in various scenarios either for logging or doing some business validations or anything which requires custom handling of your scenario. Now, let us quickly jump at demo. Below, I have pasted the custom filter code:
  1. using System.Web;    
  2. using System.Web.Mvc;    
  3.     
  4. namespace MVC_Life_Cycle.CustomFilter    
  5. {    
  6.     //Filter attribute is there to make the same accessible as attributes inside controller's methods    
  7.     //IActionFilter offcourse gives two pre and post execution methods.    
  8.     public class CustomFilter :FilterAttribute, IActionFilter    
  9.     {    
  10.         public void OnActionExecuting(ActionExecutingContext filterContext)    
  11.         {    
  12.             HttpContext.Current.Application["Filter"] += "Filter 1 Executing, <br />";    
  13.         }    
  14.     
  15.         public void OnActionExecuted(ActionExecutedContext filterContext)    
  16.         {    
  17.             HttpContext.Current.Application["Filter"] += "Filter 1 Executed, <br />";    
  18.         }    
  19.     }    
  20.     
  21.     public class CustomFilter2 : FilterAttribute, IActionFilter    
  22.     {    
  23.         public void OnActionExecuting(ActionExecutingContext filterContext)    
  24.         {    
  25.             HttpContext.Current.Application["Filter"] += "Filter 2 Executing, <br />";    
  26.         }    
  27.     
  28.         public void OnActionExecuted(ActionExecutedContext filterContext)    
  29.         {    
  30.             HttpContext.Current.Application["Filter"] += "Filter 2 Executed, <br />";    
  31.         }    
  32.     }    
  33.     
  34.     public class CustomFilter3 : FilterAttribute, IActionFilter    
  35.     {    
  36.         public void OnActionExecuting(ActionExecutingContext filterContext)    
  37.         {    
  38.             HttpContext.Current.Application["Filter"] += "Filter 3 Executing, <br />";    
  39.         }    
  40.     
  41.         public void OnActionExecuted(ActionExecutedContext filterContext)    
  42.         {    
  43.             HttpContext.Current.Application["Filter"] += "Filter 3 Executed, <br />";    
  44.         }    
  45.     }    
  46.     public class CustomFilter4 : FilterAttribute, IActionFilter    
  47.     {    
  48.         public void OnActionExecuting(ActionExecutingContext filterContext)    
  49.         {    
  50.             HttpContext.Current.Application["Filter"] += "Filter 4 Executing, <br />";    
  51.         }    
  52.     
  53.         public void OnActionExecuted(ActionExecutedContext filterContext)    
  54.         {    
  55.             HttpContext.Current.Application["Filter"] += "Filter 4 Executed, <br />";    
  56.         }    
  57.     }    
  58.     
  59.     public class CustomFilter5 : FilterAttribute, IActionFilter    
  60.     {    
  61.         public void OnActionExecuting(ActionExecutingContext filterContext)    
  62.         {    
  63.             HttpContext.Current.Application["Filter"] += "Filter 5 Executing, <br />";    
  64.         }    
  65.     
  66.         public void OnActionExecuted(ActionExecutedContext filterContext)    
  67.         {    
  68.             HttpContext.Current.Application["Filter"] += "Filter 5 Executed, <br />";    
  69.         }    
  70.     }    
  71. }  
However, the code is really simple and self explanatory. Then, I have modified the controller code. Here, I have just added the filters attribute.
  1. using System;    
  2. using System.Collections.Generic;    
  3. using System.Linq;    
  4. using System.Web;    
  5. using System.Web.Mvc;    
  6. using MVC_Life_Cycle.Utils;    
  7.     
  8. namespace MVC_Life_Cycle.Controllers    
  9. {    
  10.     public class HomeController : Controller    
  11.     {    
  12.         [CustomFilter.CustomFilter]    
  13.         [CustomFilter.CustomFilter2]    
  14.         [CustomFilter.CustomFilter3]    
  15.         [CustomFilter.CustomFilter4]    
  16.         [CustomFilter.CustomFilter5]    
  17.     
  18.         public ActionResult Index()    
  19.         {    
  20.             return View();    
  21.         }    
  22.     
  23.         [IsValidRequest]    
  24.         public JsonResult About()    
  25.         {    
  26.             return Json("{Msg: From a Custom Action Invoker!}", JsonRequestBehavior.AllowGet);    
  27.         }    
  28.     
  29.         public ActionResult About(string msg)    
  30.         {    
  31.             ViewBag.Message = "Your application description page.";    
  32.     
  33.             return View();    
  34.         }    
  35.     
  36.         public ActionResult Contact()    
  37.         {    
  38.             ViewBag.Message = "Your contact page.";    
  39.     
  40.             return View();    
  41.         }    
  42.     }    
  43. }    
Lastly, I have modified view to fetch the value and print the same.
  1. @{    
  2.     ViewBag.Title = "Home Page";    
  3. }    
  4.     
  5. <div class="jumbotron">    
  6.     <h1>Filter Execution Path</h1>    
  7.     <p class="lead">Refer MVC Life Cycle series at My View.</p>    
  8.     <p><a href="http://myview.rahulnivi.net" class="btn btn-primary btn-lg">Learn more »</a></p>    
  9. </div>    
  10.     
  11. <div>    
  12.     <span>    
  13.      @{    
  14.          //Fetching the values from Application State    
  15.          @Html.Raw(HttpContext.Current.Application["Filter"]);    
  16.      }    
  17.     </span>    
  18. </div>    
  19. <div class="row">    
  20.     <div class="col-md-4">    
  21.         <h2>Getting started</h2>    
  22.         <p>    
  23.             ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that    
  24.             enables a clean separation of concerns and gives you full control over markup    
  25.             for enjoyable, agile development.    
  26.         </p>    
  27.         <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more »</a></p>    
  28.     </div>    
  29.     <div class="col-md-4">    
  30.         <h2>Get more libraries</h2>    
  31.         <p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>    
  32.         <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more »</a></p>    
  33.     </div>    
  34.     <div class="col-md-4">    
  35.         <h2>Web Hosting</h2>    
  36.         <p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>    
  37.         <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more »</a></p>    
  38.     </div>    
  39. </div>   
With the above change in place, when I run the app, it will produce the following output.



I hope you have liked this discussion. Thanks for joining me.

Code Download Link.


Similar Articles