Archive

Posts Tagged ‘Caching’

Custom ASP.NET Cache Provider – FileSystem

May 6, 2010 Leave a comment

So works been busy. Here is how to implement a filesystem based cached provider. I real life you would use something like memcached but I post the code later 🙂 All you need to do is create class that derives from OutputCacheProvide override the Get, Add, Set and Remove methods. Also you need to tell ASP.net to use it in the web.config file.

So here we go with the code

public class FileSystemCacheProvider : OutputCacheProvider
    {

        [Serializable]
        private class CacheObject
        {
            public object Item { get; set; }
            public DateTime Expires { get; set; }
        }

        private const string prefix = "fscache";

        public override object Get(string key)
        {
            string fullpath = GetFullPathNameForCacheKey(key);

            if (!File.Exists(fullpath))
            {
                return null;
            }

            CacheObject cObject;

            using (Stream fscacheStream = new FileStream(fullpath, FileMode.Open, FileAccess.Read))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                cObject = (CacheObject)(formatter.Deserialize(fscacheStream));
                
            }

            if (cObject != null)
            {
                if (cObject.Expires <= DateTime.Now.ToUniversalTime())
                    Remove(key);
                return cObject.Item;
            }

            return null;

        }

        private static string GetFullPathNameForCacheKey(string key)
        {
            return Path.Combine(prefix, AdjustKey(key));
        }

        public static string AdjustKey(string key)
        {
            if (key.Contains(@"\"))
                return key.Replace(@"\", "-");

            if (key.Contains(@"/"))
                return key.Replace(@"/", "-");

            return key;
        }

        public override object Add(string key, object entry, DateTime utcExpiry)
        {
            string fullpath = GetFullPathNameForCacheKey(key);
            using (Stream fscacheStream = new FileStream(fullpath, FileMode.Create))
            {
                fscacheStream.Position = 0; // Reset
                CacheObject cObject = new CacheObject {Expires = utcExpiry, Item = entry};

                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(fscacheStream, cObject);
                return null;
            }
        }

        public override void Set(string key, object entry, DateTime utcExpiry)
        {
            string fullpath = GetFullPathNameForCacheKey(key);
            using (Stream fscacheStream = new FileStream(fullpath, FileMode.OpenOrCreate,FileAccess.Write))
            {

                CacheObject cObject = new CacheObject { Expires = utcExpiry, Item = entry };

                fscacheStream.Position = 0; // Reset
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(fscacheStream, cObject);
            }
        }

        public override void Remove(string key)
        {
            string fullpath = GetFullPathNameForCacheKey(key);
            if (File.Exists(fullpath))
            {
                File.Delete(fullpath);
            }
        }
    }
<?xml version="1.0"?>
<caching>
      <outputCache defaultProvider="fscacheprovider"
                   enableOutputCache="true">
        <providers>
          <add name="fscacheprovider" type="ASPNET4.FileSystemCacheProvider, ASPNET4"/>
        </providers>
      </outputCache>
    </caching>

Any questions post a comment or suggestion or bugs.

Hope this helps someone.

Blair…

Advertisements
Categories: Development Tags: , , , ,