ARTICLE

Custom Caching Provider in ASP.NET 4.0/4.5

Posted by Amit Patel Articles | ASP.NET Programming June 14, 2012
In this article I am trying to explain Custom Caching Provider in ASP.NET 4.0 or 4.5. I have created a sample in Visual Studio 2011
Reader Level:
Download Files:
 

Introduction

In this article I am trying to explain Custom Caching Provider in ASP.NET 4.0 or 4.5. I have created a sample in Visual Studio 2011.

Purpose

Caching enables you to store data in memory for rapid access. When the data is accessed again, applications can get the data from the cache instead of retrieving it from the original source. This can improve performance and scalability. In addition, caching makes data available when the data source is temporarily unavailable.

Code:

Step 1: Create two new projects; one is Web Application and the other is Class Library.

Step 2: Now open the Class Library project and add a reference for System.Web assembly.

Step 3: Now inherit your class from OutputCacheProvider Class.  

Step 4: Now override all Add, Get, Set and Remove Methods.

Here is sample Code.

public class FileCacheProvider : OutputCacheProvider
    {
       
private string _filecachePath;

        public string FilecachePath
        {
           
get
            {
               
if (!string.IsNullOrEmpty(_filecachePath))
                    return _filecachePath;
                _filecachePath = System.Configuration.
ConfigurationManager.AppSettings["OutputCachePath"];

                var context = HttpContext.Current;

                if (context != null)
                {
                    _filecachePath = context.Server.MapPath(_filecachePath);
                   
if (!_filecachePath.EndsWith("\\"))
                        _filecachePath +=
"\\";
                }

                return _filecachePath;
            }
        }
       
public override object Add(string key, object entry, DateTime utcExpiry)
        {
           
Debug.WriteLine("Cache.Add(" + key + ", " + entry + ", " + utcExpiry + ")");

            var path = GetPathFromKey(key);

            if (File.Exists(path))
                return entry;

            using (var file = File.OpenWrite(path))
            {
               
var item = new CacheItem { Expires = utcExpiry, Item = entry };
               
var formatter = new BinaryFormatter();
                formatter.Serialize(file, item);
            }

            return entry;
        }
       
public override object Get(string key)
        {
            
Debug.WriteLine("Cache.Get(" + key + ")");

            var path = GetPathFromKey(key);

            if (!File.Exists(path))
                return null;

            CacheItem item = null;

            using (var file = File.OpenRead(path))
            {
               
var formatter = new BinaryFormatter();
                item = (
CacheItem)formatter.Deserialize(file);
            }

            if (item == null || item.Expires <= DateTime.Now.ToUniversalTime())
            {
                Remove(key);
               
return null;
            }

            return item.Item;
        }
       
public override void Remove(string key)
        {
           
Debug.WriteLine("Cache.Remove(" + key + ")");

            var path = GetPathFromKey(key);

            if (File.Exists(path))
                File.Delete(path);
        }
 
       
public override void Set(string key, object entry, DateTime utcExpiry)
        {
           
Debug.WriteLine("Cache.Set(" + key + ", " + entry + ", " + utcExpiry + ")");

            var item = new CacheItem { Expires = utcExpiry, Item = entry };
           
var path = GetPathFromKey(key);
 
           
using (var file = File.OpenWrite(path))
            {
               
var formatter = new BinaryFormatter();
                formatter.Serialize(file, item);
            }
        }
       
private string GetPathFromKey(string key)
        {
           
return FilecachePath + MD5(key) + ".txt";
        }

        private string MD5(string s)
        {
            
var provider = new MD5CryptoServiceProvider();
           
var bytes = Encoding.UTF8.GetBytes(s);
           
var builder = new StringBuilder();

            bytes = provider.ComputeHash(bytes);

            foreach (var b in bytes)
                builder.Append(b.ToString(
"x2").ToLower());

            return builder.ToString();
        }
    }

Step 5: Now add the class library project reference to your web application and add the following attribute to your web.config file:

  <caching>
      <
outputCache defaultProvider="FileCacheProvider">
        <
providers>
         <
add name="FileCacheProvider" type="CustomCacheProviderLib4_5.FileCacheProvider"/>
        </
providers>
      </
outputCache>
    </caching>

Step 6: Now add an OutputCache Directive to your page (Default.aspx).

<%@ OutputCache VaryByParam="ID" Duration="300" %>

Step 7: Now run your web application and see that your page is loading from the Cache:

ASP1.jpg

Step 8: Here is the output window:

ASP2.jpg

Happy Coding!

Login to add your contents and source code to this article
post comment
     

I have implemented the disk based Custom Cache Provider which works fine except from one problem. When i use the provider in aspx Pages the generated key is of the from "a2/../../default.aspx" which is fine. When I use the same provider in User Controls the generated key is of the form "lfffffff40e80...." and this is fine till the application pool recycles. Then for the same user control a similar key is generated (but not the same) meaning that the cashed user control cannot be accessed with the new key and a new entry is generated in the Disk Cache for the same user control. This functionality makes useless all the cached controls when application pool recycles.Is this the way Custom Cache Providers work with User Controls? How can I generate the same key for the User Control when the application pool recycles?Thank you in advance!

Posted by Ioannis Dontas Jun 21, 2012

good one.

Posted by Gohil Jayendrasinh Jun 16, 2012

Thanks Sagar

Posted by Amit Patel Jun 14, 2012

Good Article! Keep going sir.

Posted by Sagar Biswas Jun 14, 2012
COMMENT USING
PREMIUM SPONSORS
DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and add new content to existing PDF documents from within your applications.
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.
Get Career Advice from Experts