Search code examples
c#asp.net-mvc-3action-filter

ActionFilter not firing after setting result in controller.OnActionExecuting


I have a global action filter that is setting the MasterPage of all ViewResults during the OnActionExecuting event.

In a number of my controllers (where each controller represents a feature of the application) I need to check to see if the feature is enabled and if not, return a different View.

Here's the code:

    protected override void OnActionExecuting(ActionExecutingContext filterContext) {
        if (!settings.Enabled)
        {
            filterContext.Result = View("NotFound");
        }

        base.OnActionExecuting(filterContext);
    }

The problem is that when setting the result like this, my ActionFilter's OnActionExecuted method does not fire, meaning I do not get the correct MasterPage applied.

I would like to understand why this happens. One remedy is to move my ActionFilter logic into OnResultExecuting (this does fire), but I am still confused as to why OnActionExecuted does not.

Many thanks

Ben


Solution

  • If you assign a result to the filterContext.Result inside an OnActionExecuting then the action won't execute => the OnActionExecuted will never run. So you might need to apply the correct master page inside the OnActionExecuting event when returning the NotFound view:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!settings.Enabled)
        {
            // Because we are assigning a Result here the action will be 
            // short-circuited and will never execute neither the OnActionExecuted
            // method of the filer. The NotFound view will be directly rendered
            filterContext.Result = new ViewResult
            {
                ViewName = "NotFound",
                MasterName = GetMasterName()
            };
        }
    }