Community Post

Action Filters in ASP.NET MVC 5

GrandNode

In ASP.NET MVC, controllers define action methods that usually have a one-to-one relationship with possible user interactions, such as clicking a link or submitting a form. For example, when the user clicks a link, a request is routed to the designated controller, and the corresponding action method is called. Sometimes you want to perform logic either before an action method is called or after an action method runs. To support this, ASP.NET MVC provides filters. Filters are custom classes that provide both a declarative and programmatic means to add pre-action and post-action behavior to controller action methods. ASP.NET MVC supports the following types of action filters:

**1. Authentication

  1. Authorization
  2. Action
  3. Result
  4. Exception**

Today we'll show you an example of using Action filters in the nopCommerce. Action filters: These implement IActionFilter and wrap the action method execution. The IActionFilter interface declares two methods: OnActionExecuting and OnActionExecuted. OnActionExecuting runs before the action method. OnActionExecuted runs after the action method and can perform additional processing, such as providing extra data to the action method, inspecting the return value or canceling execution of the action method. Here are some use cases action filters nopCommerce using the plugin.

Case 1: Task: When registering a new client we want to validate the field Vat Number - In the case erroneously supplemented let the system informs the user about the error. We prepare new class RegisterFilterProvider, it should be inherit from ActionFilterAttribute, IFilterProvider We need to specify when to acttion filter should be run. The code should looks like:

       public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
       {
           if ((actionDescriptor.ControllerDescriptor.ControllerType == typeof(CustomerController)) &&
                   (actionDescriptor.ActionName.Equals("Register")) && controllerContext.HttpContext.Request.HttpMethod == "POST")
           {               
               return new List<Filter>() { new Filter(this, FilterScope.Action, 0) };
           }
           return new List<Filter>() { };
       }

Now you have to write the actual code field validation VAT Number during registration. We use OnActionExecuting(ActionExecutedContext filterContext) - Just before the action method is called.

The sample code that does so looks like:

       public override void OnActionExecuting(ActionExecutingContext filterContext)
       {
           var formCollection = new FormCollection(filterContext.HttpContext.Request.Form);
           string vatNumber = formCollection["VatNumber"];
           //...your logic ...

           if (String.IsNullOrEmpty(vatNumber))
           {
               filterContext.Controller.ViewData.ModelState.AddModelError("", "Sample text - incorrect vat number");
           }
       }

Last thing we need to do is register the class in AutoFac. To register classes in AutoFac in nopCommerce, we use DependencyRegistrar.cs. Sample code: builder.RegisterType().As();

Case 2: Task: After registering a new customer (If the field VAT is correct, assign to the role Company) We use OnActionExecuted(ActionExecutingContext filterContext) - After the action method is called and before the result is executed (before view render). Sample code:


   public class RegisterFilterProvider : ActionFilterAttribute, IFilterProvider
   {
      public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
      {
          if ((actionDescriptor.ControllerDescriptor.ControllerType == typeof(CustomerController)) &&
                 (actionDescriptor.ActionName.Equals("Register")) && controllerContext.HttpContext.Request.HttpMethod == "POST")
          {     
               return new List<Filter>() { new Filter(this, FilterScope.Action, 0) };
          }
          return new List<Filter>() { };
      }
      public override void OnActionExecuted(ActionExecutedContext filterContext)
       {
           if (filterContext.Result.GetType() == typeof(RedirectResult) || filterContext.Result.GetType() == typeof(System.Web.Mvc.RedirectToRouteResult))
           {
               var formCollection = new FormCollection(filterContext.HttpContext.Request.Form);
               string vatNumber = formCollection["VatNumber"];
               //...your logic ...
               if (!String.IsNullOrEmpty(vatNumber))
               {
                   var customerService = EngineContext.Current.Resolve<ICustomerService>();
                   var companyRole = customerService.GetCustomerRoleBySystemName("Company");
                   if(companyRole!=null)
                   {
                       var customer = EngineContext.Current.Resolve<IWorkContext>().CurrentCustomer;
                       customer.CustomerRoles.Add(companyRole);
                       customerService.UpdateCustomer(customer);
                   }
              }
   }               

Do not forget to register classes in AutoFac in nopCommerce.

You can download full sample source code for nopCommerce below.

DOWNLOAD

Also please check our newest release of GrandNode. 3.90 is available now for download and use. On our github you can look at full change log, there is many changes and we are convinced that it is project of future. Feel free to leave us feedback and any suggestions.

https://github.com/grandnode/grandnode/