ASP.NET cache and session with Redis and CacheManager

How to use Redis as a session provider and a cache provider for ASP.Net solution. To make solution flexible for cache backend we use CacheManager.

Source code is available here https://github.com/mchudinov/AspCacheRedis


Control your Redis

I use Redis Desktop Manager. It is a free and simple application running on Windows, Linux, MacOS. Redis Desktop Manager provides easy-to-use GUI to access your Redis DB and perform some basic operations: view keys as a tree, CRUD keys, execute commands via shell.

Session in Redis

Useful link How to use configuration parameters of Session State Provider and Output Cache Provider

1. Install packages

2. Write a serializer class

This step is only needed if we are going to put NOT serializable objects to the session. If we have no control over it in the project then better to add a serializer. It’s just a tiny class and a one configuration option. This class must extend Microsoft.Web.Redis.ISerializer interface.

public class JsonSerializer : Microsoft.Web.Redis.ISerializer
{
	private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };

	public byte[] Serialize(object data)
	{
		return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data, Settings));
	}

	public object Deserialize(byte[] data)
	{
		return data == null ? null : JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), Settings);
	}
}

3. Add a session provider definition in web.config

  <system.web>
    <sessionState mode="Custom" customProvider="RedisSessionState">
      <providers>
        <add 
          name="RedisSessionState" 
          type="Microsoft.Web.Redis.RedisSessionStateProvider" 
          host="...." 
          ssl="true" 
          port="6380" 
          databaseId="0" 
          accessKey="...." 
          redisSerializerType = "AspCacheRedis.JsonSerializer,AspCacheRedis"/>
      </providers>
    </sessionState>
  </system.web>

Where redisSerializerType is the created serializer class option.

Now your application is ready to place session data in Redis.

Cache in Redis

To make solution flexible for cache backend we use CacheManager. CacheManager supports various cache providers and it is easy to switch between them. For example it is possible to use System.Web.Caching.Cache while developing and Redis in production by only changing configuration.

My blogpost about common cache interface and implementations

1. Install packages

2. CacheManager configuration for Redis

Useful link all valid configurations options in *.config file.

  <cacheManager.Redis>
    <connections>
      <connection id="RedisHandle" database="0" connectionString="......:6380,password=.....,ssl=True,abortConnect=False" />
    </connections>
  </cacheManager.Redis>

  <cacheManager>
    <managers>
      <cache name="Redis" updateMode="Up" enableStatistics="false" enablePerformanceCounters="false" 
             serializerType="CacheManager.Serialization.Json.JsonCacheSerializer, CacheManager.Serialization.Json">
        <handle name="RedisHandle" ref="RedisHandle" />
      </cache>    
    </managers>
    <cacheHandles>
      <handleDef id="RedisHandle" type="CacheManager.Redis.RedisCacheHandle`1, CacheManager.StackExchange.Redis" />
    </cacheHandles>
  </cacheManager>

3. Serialization

Serialization is needed for non serializable objects for distributed (not in-process) cache systems which is Redis.
Useful link CacheManager serialization documentation.
To enable caching for non serializable objects we need to use CacheManager.Serialization.Json.
Install the package and add the following line to config for this for the Redis cache manager:
serializerType="CacheManager.Serialization.Json.JsonCacheSerializer, CacheManager.Serialization.Json

Done!
Now our ASP.Net solution is ready to use Redis through CacheManger as a caching backend.
Use it:

ICacheProvider cacheManager = new CacheManagerCache();
cacheManager.Set("key", "Hello from Redis through CacheManager!");
var temp = cacheManager.Get<string>("key");