Controller.OnActionExecuting not firing after first visit to action

2.5k views Asked by At

In my MVC 4 web app, I have a requirement to ask users to choose a payment method after they have been using the app for a certain number of days.

I've implemented this by making a controller base class, and making all my controllers inherit from this. The base class has the following code:

public class MyBaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (WebSecurity.IsAuthenticated)
        {
            var pay = PaymentDetails.LoadByMember(WebSecurity.CurrentUserId);
            if (pay.ForceToChooseMandate)
            {
                filterContext.Result = RedirectToAction("Choose", "Payment");
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

The Choose action has links allowing you to set up payment details or to defer choosing for a while. If either of these links are visited then pay.ForceToChooseMandate returns false on subsequent calls, allowing normal operation of the app to be resumed for the user.

That first time an action gets visited, OnActionExecuting fires and the redirect works as fine. But if the user visits the action a second time, OnActionExecuting never fires, and they are redirected to the Choose action again, even though pay.ForceToChooseMandate would have evaluated to false for them this time.

However if they visit a previously unvisited action, OnActionExecuting fires as expected.

How can I stop this happening, and have OnActionExecuting always fire so it can always reflect the users' current state?

1

There are 1 answers

1
Mihai Dinculescu On BEST ANSWER

The problem is that the result of your first execution is cached.

In order to achieve what you want, you need to disable caching for the Actions in questions. You can do this by decorating those Actions with OutputCacheAttribute

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]

You can also keep cache enabled but specify VaryByParam to refresh it when needed.

Alternatively you can remove the cache of an action from another action by using

HttpResponse.RemoveOutputCacheItem("/Home/About");