ASP.NET Output Caching in SharePoint

So you’re developing your web parts and web sites and everything is working perfectly; a little slow, but, otherwise fine.  In comes the idea of caching.  Caching should speed up your web site’s performance considerably.

In my case this was all too easy to implement since I’m developing in SharePoint.  Simply go to the site collection output cache settings and enable.  Everything seems to run fine when testing it until you give it to the end users.  All of a sudden users are seeing other users’ data.  Not good.  At least SharePoint is good enough to cache a different page per set of user rights.

The fix?

Post Cache Substitution

If you want to do simple post cache substitution SharePoint provides you with the PostCacheSubstitutionText class. It’s quite limited in what it can do, but, more importantly it gives an example of how to do post cache substitution.  The PostCacheSubstitution class shows how to inject string data into the ASP.Net HttpResponse.

The basics of it are as follows:

  1. Create a regular control to use in a .NET web page / SharePoint page.
  2. Create a helper class that handles the caching callbacks.
  3. Implement your controls render function.

Here’s an example:

[code language=”csharp”]
public class MySubstitutionControl : UserControl
{
protected override void Render(HtmlTextWriter output)
{
MySubstitutionHelper helper = new MySubstitutionHelper();
helper.RegisterSubstitutionCallback(HttpContext.Current);
}

protected string PostCacheRender()
{
return “<div><p>This was created post cache!</p></div>”;
}
}

internal class  MySubstitutionHelper
{
internal void RegisterSubstitutionCallback(HttpContext context)
{
HttpResponseSubstitutionCallback callback = new HttpResponseSubstitutionCallback(this.SubstitutionCallback);
context.Response.WriteSubstitution(callback);
}

internal string SubstitutionCallback(HttpContext context)
{
MySubstitutionControl control = new MySubstitutionControl();
return control.PostCacheRender();
}
}
[/code]

And, based on my limited knowledge of ASP.NET internals here’s how it works:

  • The initial page render renders our control. However, since IsForPostCacheSubstitution is false it calls the helper method which instead renders a special substitution tag in place of our control into the page.
  • The page gets cached.
  • The ASP.NET engine then looks for said special substitution tags after loading the page from the cache. It then runs the Substitution callback which instantiates our control and returns what should actually be rendered.
  • The ASP.NET engine then replaces the substitution tag with what we want.

For more information:

Page Output Caching: http://msdn.microsoft.com/en-us/library/ms972362.aspx
SharePoint Output Caching: http://msdn.microsoft.com/en-us/library/aa661294(v=office.14).aspx