Search code examples
c#asp.netcachingwebformsoutputcache

Output page and session page state


I want to add outputcache to my ASP.NET website. However, there is some code behind that changes some buttons and content based on whether the user is logged in or not. I am afraid that if I use it, it might cache the page with the code for a logged in user. Is this how it works, or whether I have to configure something so it will work with sessions?


Solution

  • You need to do the following changes:

    Add VaryByCustom attribute and set its value to User in your OutputCache directive like this :

    <%@ OutputCache VaryByCustom="User" .... %>
    

    Then in your Global.asax file you need to override GetVaryByCustomString method like this :

    public override string GetVaryByCustomString(HttpContext context, string custom)
    {
        if (custom.Equals("User", StringComparison.InvariantCultureIgnoreCase))
        {
            // Return the user name/login as a value that will invalidate cache per authenticated user. 
            return context.User.Identity.Name;
        }
        return base.GetVaryByCustomString(context, custom);
    }
    

    Based on your comments below to this anwser, you say you're using Session variable to check if user is logged in or not. Let me tell you that is not the best practices to manage authentication like that.

    Any way the solution to invalidate cache depending on a session value is doing this :

    <%@ OutputCache VaryByCustom="Session" .... %>
    

    Again VaryByCustom can be any string value you want by giving it a meaning string is really good and let the future devs or you to know what you was doing.

    Then override

    public override string GetVaryByCustomString(HttpContext context, string custom)
    {
        if (custom.Equals("Session", StringComparison.InvariantCultureIgnoreCase))
        {
            // make sure that the session value is convertible to string
            return (string)context.Session["Here you put your session Id"];
        }
        return base.GetVaryByCustomString(context, custom);
    }
    

    That is all you need to do. Hope it helps.