Click here to Skip to main content
Click here to Skip to main content
Articles » Web Development » ASP.NET » General » Downloads
 
Add your own
alternative version

ASP.NET MVC controller action with Interceptor pattern

, 2 Oct 2012 CPOL
This article is to demonstrate interceptor pattern with MVC controller action, and so action can be intercepted in controller classes without using action filters.
MvcCallInterceptors_Source_Code_and_Demo-noexe.zip
MvcCallInterceptorsDemo
MvcCallInterceptors
bin
Controllers
Interceptors
MvcCallInterceptors.csproj.user
MVCInterceptorComponents.cd
Properties
MvcCallInterceptorsDemo
App_Data
ASPNETDB.MDF
aspnetdb_log.ldf
bin
Content
themes
base
images
ui-bg_flat_0_aaaaaa_40x100.png
ui-bg_flat_75_ffffff_40x100.png
ui-bg_glass_55_fbf9ee_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_glass_75_dadada_1x400.png
ui-bg_glass_75_e6e6e6_1x400.png
ui-bg_glass_95_fef1ec_1x400.png
ui-bg_highlight-soft_75_cccccc_1x100.png
ui-icons_222222_256x240.png
ui-icons_2e83ff_256x240.png
ui-icons_454545_256x240.png
ui-icons_888888_256x240.png
ui-icons_cd0a0a_256x240.png
Controllers
Global.asax
Models
MvcCallInterceptorsDemo.csproj.user
Properties
Scripts
Views
Account
Home
Shared
packages
EntityFramework.4.1.10331.0
EntityFramework.4.1.10331.0.nupkg
lib
jQuery.1.5.1
Content
Scripts
jQuery.1.5.1.nupkg
jQuery.UI.Combined.1.8.11
Content
Content
themes
base
images
ui-bg_flat_0_aaaaaa_40x100.png
ui-bg_flat_75_ffffff_40x100.png
ui-bg_glass_55_fbf9ee_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_glass_75_dadada_1x400.png
ui-bg_glass_75_e6e6e6_1x400.png
ui-bg_glass_95_fef1ec_1x400.png
ui-bg_highlight-soft_75_cccccc_1x100.png
ui-icons_222222_256x240.png
ui-icons_2e83ff_256x240.png
ui-icons_454545_256x240.png
ui-icons_888888_256x240.png
ui-icons_cd0a0a_256x240.png
Scripts
jQuery.UI.Combined.1.8.11.nupkg
jQuery.Validation.1.8.0
Content
Scripts
jQuery.Validation.1.8.0.nupkg
jQuery.vsdoc.1.5.1
Content
Scripts
jQuery.vsdoc.1.5.1.nupkg
Modernizr.1.7
Content
Scripts
Modernizr.1.7.nupkg
MvcCallInterceptors_Source_Code_and_Demo.zip
App_Data
EntityFramework.dll
MvcCallInterceptors.dll
MvcCallInterceptors.csproj.user
MVCInterceptorComponents.cd
obj
Debug
TempPE
ASPNETDB.MDF
aspnetdb_log.ldf
EntityFramework.dll
MvcCallInterceptors.dll
MvcCallInterceptorsDemo.dll
ui-bg_flat_0_aaaaaa_40x100.png
ui-bg_flat_75_ffffff_40x100.png
ui-bg_glass_55_fbf9ee_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_glass_75_dadada_1x400.png
ui-bg_glass_75_e6e6e6_1x400.png
ui-bg_glass_95_fef1ec_1x400.png
ui-bg_highlight-soft_75_cccccc_1x100.png
ui-icons_222222_256x240.png
ui-icons_2e83ff_256x240.png
ui-icons_454545_256x240.png
ui-icons_888888_256x240.png
ui-icons_cd0a0a_256x240.png
Global.asax
MvcCallInterceptorsDemo.csproj.user
obj
Debug
TempPE
EntityFramework.4.1.10331.0.nupkg
EntityFramework.dll
jQuery.1.5.1.nupkg
ui-bg_flat_0_aaaaaa_40x100.png
ui-bg_flat_75_ffffff_40x100.png
ui-bg_glass_55_fbf9ee_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_glass_75_dadada_1x400.png
ui-bg_glass_75_e6e6e6_1x400.png
ui-bg_glass_95_fef1ec_1x400.png
ui-bg_highlight-soft_75_cccccc_1x100.png
ui-icons_222222_256x240.png
ui-icons_2e83ff_256x240.png
ui-icons_454545_256x240.png
ui-icons_888888_256x240.png
ui-icons_cd0a0a_256x240.png
jQuery.UI.Combined.1.8.11.nupkg
jQuery.Validation.1.8.0.nupkg
jQuery.vsdoc.1.5.1.nupkg
Modernizr.1.7.nupkg
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcCallInterceptors.Interceptors;

namespace MvcCallInterceptors.Controllers
{
    internal class BaseControllerInterceptorInvoker : ControllerActionInvoker
    {
        protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (actionDescriptor == null)
            {
                throw new ArgumentNullException("actionDescriptor");
            }
            if (actionDescriptor == null)
            {
                throw new ArgumentNullException("parameters");
            }
            _canResultConvertedToActionResult = true;

            var basecontroller = controllerContext.Controller as BaseMvcController;
            if (basecontroller != null)
            {
                bool terminateAll = false;
                bool sendResult;
                IEnumerable<ActionInterceptor> interceptors;

                interceptors = InterceptorsRegistry.GetInterceptors(basecontroller, actionDescriptor);
                //.OrderBy((t) => t.ActionInterceptorProperties.<If there is any specific order needs to be given>);

                InterceptorExecutionContext context = new InterceptorExecutionContext(controllerContext, interceptors, parameters);

                var before = interceptors.Where((t) => t.ActionInterceptorProperties.InterceptionOrder == InterceptionOrder.Before);

                foreach (var interceptor in before)
                {
                    ExecuteInterceptor(context, interceptor, out terminateAll, out sendResult);
                    if (terminateAll && !sendResult)
                    {
                        throw new Exception(context.ChainofExecutionTerminationMessage);
                    }
                    else if (terminateAll)
                    {
                        break;
                    }
                }
                //controller last result
                //action parameters
                if (!terminateAll)
                {
                    _canResultConvertedToActionResult = false;
                    var result = base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
                    context.InterceptorResult = _interceptorResult;
                    _canResultConvertedToActionResult = true;

                    var after = interceptors.Where((t) => t.ActionInterceptorProperties.InterceptionOrder == InterceptionOrder.After);
                    foreach (var interceptor in after)
                    {
                        ExecuteInterceptor(context, interceptor, out terminateAll, out sendResult);
                        if (terminateAll && !sendResult)
                        {
                            throw new Exception(context.ChainofExecutionTerminationMessage);
                        }
                        else if (terminateAll)
                        {
                            break;
                        }
                    }
                }
                return CreateActionResult(controllerContext, actionDescriptor, context.InterceptorResult);
            }
            else
            {
                return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
            }
        }


        private void ExecuteInterceptor(InterceptorExecutionContext context, ActionInterceptor actionInterceptor, out bool terminateAll, out bool sendResult)
        {
            terminateAll = false;
            sendResult = true;
            if (context == null)
            {
                throw new ArgumentNullException("controllerContext");
            }

            var Dispatcher = new InterceptMethodDispatcher(actionInterceptor.InterceptorMethodInfo);
            var controller = Activator.CreateInstance(actionInterceptor.InterceptorControllerType) as IInterceptorMvcController;
            controller.SetInterceptContext(context);
            context.CurrentInterceptor = actionInterceptor;
            context.SetInterceptorStatus(InterceptorExecutionStatus.Executing);
            try
            {
                object newReturnValue = Dispatcher.Execute(controller, context.ActionParameters, context.InterceptorResult);
                if ((actionInterceptor.InterceptorMethodInfo.ReturnType != typeof(void)))
                {
                    context.InterceptorResult = newReturnValue;
                }

            }
            catch (Exception ex)
            {
                if (actionInterceptor.ActionInterceptorProperties.BreakExecutionOnException)
                {
                    context.CancelAllExecutionsWithTerminationMessage(string.Empty);
                    terminateAll = true;
                    throw;
                }
                else
                {
                    context.SetInterceptorStatus(InterceptorExecutionStatus.ExceptionThrown);
                    context.Exceptions.Add(ex);
                    //log mechanism to catch exception
                }
            }
            if (context.CancelAllExecutions)
            {
                terminateAll = true;
            }

            if (!string.IsNullOrWhiteSpace(context.ChainofExecutionTerminationMessage))
            {
                sendResult = false;
            }

            if (context.GetInterceptorStatus() != InterceptorExecutionStatus.ExceptionThrown)
            {
                context.SetInterceptorStatus(InterceptorExecutionStatus.Executed);
            }

        }

        bool _canResultConvertedToActionResult = true;
        object _interceptorResult;
        protected override ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
        {
            if (_canResultConvertedToActionResult)
            {
                return base.CreateActionResult(controllerContext, actionDescriptor, actionReturnValue);
            }
            _interceptorResult = actionReturnValue;
            return new EmptyResult();

        }

        public MvcCallInterceptors.Interceptors.InterceptorExecutionContext InterceptorExecutionContext
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal MvcCallInterceptors.Interceptors.InterceptMethodDispatcher InterceptMethodDispatcher
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

amargujrathi2006
Technical Lead
India India
Like to dream on long drive and falling asleep on short drive..!

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411022.1 | Last Updated 2 Oct 2012
Article Copyright 2012 by amargujrathi2006
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid