Search code examples
c#asp.net-mvchttpsession

Session Timeout Doesn't Hit the Action Filter


I have enabled the session timeout in Startup.Auth.cs:

 app.UseCookieAuthentication(new CookieAuthenticationOptions
 {
       ExpireTimeSpan = TimeSpan.FromMinutes(1)
 }

setting it to 1 min for testing. Now I have created an action filter:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext ctx = HttpContext.Current;


        base.OnActionExecuting(filterContext);
    }
}

and registered it in FilterConfig.cs by adding filters.Add(new SessionExpireFilterAttribute());. I have also placed the attribute [SessionExpireFilter] on the customercontroller class.

Now what happens is that if I click a button that sends a request to an action customer/edit while the session has expired, the the code does hit a breakpoint in the customercontroller constructor and then a 200 is returned. It never hits the breakpoint in the actionfilter. It also never hit the actual action edit either.

Any ideas?

Thank you.


Solution

  • Remove Cache-Control from HTTP header.

    Prevent caching in MVC, we created our own attribute, you could do the same. Here's our code:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class NoCacheAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            filterContext.HttpContext.Response.Cache.SetNoStore();
    
            base.OnResultExecuting(filterContext);
        }
    }
    

    Then just decorate your controller with [NoCache]. OR to do it for all you could just put the attribute on the class of the base class that you inherit your controllers from (if you have one) like we have here:

    [NoCache]
    public class ControllerBase : Controller, IControllerBase
    

    You can also decorate some of the actions with this attribute if you need them to be non-cacheable, instead of decorating the whole controller.

    Or you can use the built in cache attribute to prevent caching.

    For .net Framework: [OutputCache(NoStore = true, Duration = 0)]

    For .net Core: [ResponseCache(NoStore = true, Duration = 0)]