Friday, May 31, 2013

asp.net - OutputCache, page level caching dynamically

I wanted to setup page level caching for one of the web application I was building since the content of the site came from a database and the content was not updated frequently.
Instead of using the declarative syntax
<%@ OutputCache Duration="20" VaryByParam="param1;param2"%> 
I use the following CachePage() method that enables caching based on configuration entries.

More on various caching techniques here (http://msdn.microsoft.com/en-us/library/y18he7cw(v=vs.100).aspx)

The following configuration entries help control how often the pages are to be cached and the query string parameter values that would invalidate the cache.

Web.Config

<add key="ENABLE_PAGE_CACHE" value="true"/>
<add key="CACHE_DURATION_UNIT" value="SECONDS"/><!--SECONDS,MINUTES,DAYS,HOURS-->
<add key="CACHE_DURATION_VALUE" value="10"/>
 <add key="CACHE_CLEAR_PARAMS" value="param1;param2"/><!--query string parameters separated by ; -->

ASPX Page

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CachingExample
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
       {
           if(!IsPostback)
          {
               //GetPageContentFromDB
               if(Convert.ToBoolean(ConfigurationManager.AppSettings["ENABLE_PAGE_CACHE"]) 
               CachePage();
            }
            
        }
    }
}

CachePage() Method

protected void CachePage()
        {
            try
            {
                string sCacheDurationUnit = ConfigurationManager.AppSettings["CACHE_DURATION_UNIT"];
                int iCacheDurationValue = Convert.ToInt32(ConfigurationManager.AppSettings["CACHE_DURATION_VALUE"]);
                string [] saCacheVaryParam = ConfigurationManager.AppSettings["CACHE_CLEAR_PARAMS"].Split(';');

                switch (sCacheDurationUnit)
                {
                    case "SECONDS":
                        Response.Cache.SetExpires(DateTime.Now.AddSeconds(iCacheDurationValue));
                        break;
                    case "MINUTES":
                        Response.Cache.SetExpires(DateTime.Now.AddMinutes(iCacheDurationValue));
                        break;
                    case "HOURS":
                        Response.Cache.SetExpires(DateTime.Now.AddHours(iCacheDurationValue));
                        break;
                    case "DAYS":
                        Response.Cache.SetExpires(DateTime.Now.AddDays(iCacheDurationValue));
                        break;
                    default:
                        Response.Cache.SetExpires(DateTime.Now.AddSeconds(iCacheDurationValue));
                        break;
                }
                
                Response.Cache.SetCacheability(HttpCacheability.Public);
                Response.Cache.SetValidUntilExpires(true);

                foreach(string sCacheVaryParam in saCacheVaryParam)
                    Response.Cache.VaryByParams[sCacheVaryParam] = true;

            }
            catch (Exception ex)
            {
                LogError("Caching error " + _oSessionInfo.sMachineId + ".", _oSessionInfo, null, ex);
            }
        }