ASP.NET Core Web Application Session State Management & Redis Implementation

Muhammet Kaya
6 min readJul 5, 2020

--

Hi Everyone :)

Caches are important part of our development cycle especially in microservice architecture. And this architecture makes service scalability pretty easier. ASP.NET Web Application’s stores session state in their own memory. In this story I’ll show you how integrate Redis for session state management in ASP.NET Core and share more details.

Prerequisites

  • Redis
  • Redis-Cli
  • Net Core 3.1
  • Docker

Introduction

Before we start we have to prepare environment. And create redis instance. So, let’s start with creating redis instance in our local machine. (If you have AWS or Azure account you can use redis instance on cloud.)

For this project I’ll use official redis docker image. To create instance run code below on your terminal. (If you want to detached container simply you can add “-d”)

docker run --name dist-session-container -p 6379:6379 -d redis

After running this code you’ll see like this;

Redis Container startup

Now, We have a redis instance in our local machine that is published in 6379 port. (6379 is default Redis port. And while running container we mapped main machine’s 6379 to port to containers 6379 port.)

Let’s create basic ASP.NET Web Application using dotnet cli. (“-o dist-session-management” creates directory that is called “dist-session-management”)

dotnet new webapp -o dist-session-management --auth None

After running this code dotnet cli will create a web application project for you. And folder structure seems like below.

ASP.NET Core Web App Folder Structure

Now we are ready to build session management.

If you have face PR_END_OF_FILE_ERROR while running the new application. You should reset http certificates. For mac users they can run code below.

dotnet dev-certs https -trust

Basic Session State Management Integration

To use session state, we need to add some code to our Startup.cs to figure out session management. Basically, your default Startup.cs like this;

Default Startup.cs

Now we’ll add some code blocks to our Startup.cs.

“AddSession” is for registering/inject session services to our service container in “ConfigureServices” method. (Dependency Injection)

Registering session service

“UseSession” is for adding session middleware to our request pipeline in “Configure” method.

Added session middleware to request pipeline

After adding these 2 code block to Startup.cs, we are ready to use sessions. We can add some key and values using HttpContext.Session. Now it consumes in memory cache. We’ll add Redis later :)

P.S.

Startup.cs includes “ConfigureServices” and “Configure” methods. ConfigureServices method add services to your service container. Service container provides services to your project. (You can register your interface as well.) As for “Configure” Method configures your http request pipeline. You can added middlewares here.

Let’s add some value to our session :)

In ASP.NET Core, We access user session on HttpContext’s Session property. Basically, this property Set(key:string, value:byte[]) and Get(key:string) extensions. Mostly .NET Developer’s use SetString(key:string, value:string) and GetString(key:string) methods that comes with “Microsoft.AspNetCore.Http.SessionExtensions”

Now, Let’s add “testKey” and “testValue” to the session in Index page.

Index.cshtml.cs

When we call the SetString() method, it will serialize your data to byte array then save your data in key value store that is uncommitted. Let’s have look session object closer with reflection. Below, you will see private fields on Session object.(Sorry for translation)

Session Object

_sessionId: Session id that is store in server side.

_sessionKey: Session key that is stored client side cookie.

_store: Uncommitted session’s key value store.

_cache: Committed session’s key value store.

_idleTimeout: Session timeout. (We’ve configured it at the Startup.cs)

Now we are still in OnGet Action (BTW I’m debugging :)) Even if, I’ve passed the HttpContext.Session.SetString line our session values are still in uncommitted key value store. As you see below our _cache has no member.(Count = 0)

Committed Session Key Value Store (Empty)

As you know we’ve added Session Middleware to our pipeline in our Startup.cs. (With UseSession() Extension) This middleware stores our session into committed session key value store. If you set log level information you will see the middleware logs about session.

SessionMiddleware Commit Log

After SessionMiddleware works, We will see our session (“0f81321e-5cb5–703d-af9d-545b493be73d”) into committed session key value store and stored by sessionKey.

Committed Session Key Value Store

Redis Session Implementation

We’ve understood how session and SessionMiddleware works. Now, it’s time to implement Redis. At the beginning of the story we’ve already created Redis Instance in our local machine using Docker.

For Redis Session Implementation We’ll just add a new connection string and override IDistributedCache Interface using AddDistributedCache Extension in our Startup.cs. To register new distributed cache service we need to add a package that is called “Microsoft.Extensions.Caching.Redis”.

dotnet add package Microsoft.Extensions.Caching.Redis

After adding this package we’ve just need to change our ConfigureServices method(in Startup.cs) like below

When we added “AddedDistributedRedisCache” it will override default DistributedCacheService that is consumed by Session Service. And current SessionService will store session state on Redis Cache by using new DistributedCacheService.

And If you configure Redis instance like me (docker run command at the introduction part) adding this code block is enough for our project. Thats it :)

Now, Let’s check our redis cache using redis cli. We’ve stored session states with “Session_” prefix.

To check our keys in Redis you can use code below

KEYS *Session*
redis-cli KEYS command

If you see this line I’m would like to say thank you so much for reading. I hope you’ve enjoyed while reading or you might have learned something in this story.

See you in next stories.. :)

Source Code

Resources

My Highlighted Articles

--

--

Muhammet Kaya

Senior Software Developer @DrDoctor, Formerly @Setur, @LogoBusinessSolution