In-Memory vs Distributed Sessions in ASP.NET Core MVC

SPONSOR AD

In-Memory or In-Proc vs. Distributed or Out-Proc Sessions in ASP.NET Core MVC

In this article, I will discuss In-Memory or In-Proc vs Distributed or Out-Proc Sessions in ASP.NET Core MVC Applications with Examples. Please read our previous article discussing Sessions in ASP.NET Core MVC Application.

In-Memory or In-Proc vs. Distributed or Out-Proc Sessions in ASP.NET Core MVC

In ASP.NET Core MVC, managing session state is an important aspect of web application development. The choice between In-Memory (In-Proc) and Distributed (Out-Proc) sessions impacts the application’s scalability, performance, and reliability.

In-Memory (In-Proc) Sessions in ASP.NET Core MVC
  • Storage: Session data is stored in the memory of the web server.
  • Performance: Generally faster since the data is stored in the same process as the web application.
  • Scalability: Limited scalability. It is not suitable for web applications that require load balancing across multiple servers because session data is tied to a specific server.
  • Reliability: All session data is lost if the web server goes down.
  • Use Case: Ideal for small-scale applications with a single server and less critical session data.
Distributed (Out-Proc) Sessions in ASP.NET Core MVC
  • Storage: Session data is stored outside the web server, typically in a distributed cache or database like Redis, SQL Server, etc.
  • Performance: This can be slower than in-memory sessions due to network latency and the time required to serialize/deserialize session data.
  • Scalability: Highly scalable. Suitable for applications deployed in a load-balanced environment across multiple servers.
  • Reliability: More reliable as session data is not lost if a single server goes down.
  • Use Case: Ideal for large-scale applications that require high availability and are deployed in a distributed environment.

Using In-Memory (In-Proc) and Distributed (Out-Proc) sessions in ASP.NET Core MVC involves different configurations and considerations. Let us proceed and understand how to Implement In-Memory (In-Proc) and Distributed (Out-Proc) sessions in the ASP.NET Core MVC Application.

Implementing In-Memory (In-Proc) Sessions in ASP.NET Core MVC:

The In-Memory or In-Proc session state is stored in the web server’s memory. It’s fast but unsuitable for web applications running on multiple servers (like in a web farm) since the session state is local to a server.

SPONSOR AD

Implementing in-memory or in-proc (in-process) sessions in ASP.NET Core MVC involves a few key steps. The in-memory session storage is suitable for single-server scenarios where you don’t need to persist data across server restarts.

Configure Services for Session:

In your Program.cs file (since ASP.NET Core 6 no longer uses Startup.cs by default), configure the session services. This includes adding a distributed memory cache and session services.

// Add Session services to the container.
builder.Services.AddDistributedMemoryCache();

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30); // e.g. 30 minutes session timeout
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});
Use Session Middleware

In the same Program.cs file, ensure the session middleware is added to the application’s request pipeline. This should be done before routing and endpoints middleware.

app.UseRouting();

app.UseSession(); // Add this line to use session

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
Using Sessions in Controllers

In your controllers, you can access the session via the HttpContext.

using Microsoft.AspNetCore.Mvc;
namespace SampleMVCWeb.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            // Set a value in session
            HttpContext.Session.SetString("MySessionKey", "MySessionValue");
            return View();
        }

        public IActionResult AnotherAction()
        {
            // Retrieve the value from session
            var value = HttpContext.Session.GetString("MySessionKey");
            ViewBag.SessionValue = value;
            return View();
        }
    }
}

Implementing Distributed (Out-Proc) Sessions in ASP.NET Core MVC:

Distributed sessions are suitable for applications running on multiple servers. The session state is stored in an external storage like Redis or SQL Server.

Implementing distributed (out-of-process) sessions in ASP.NET Core MVC to store session data in SQL Server involves several steps. This approach is useful when you have a web farm scenario (multiple servers hosting your application), and you want to ensure session data is consistent across servers.

Add Required Packages

First, add the necessary NuGet packages to your project:

SPONSOR AD
  • Microsoft.EntityFrameworkCore.SqlServer for Entity Framework Core with SQL Server.
  • Microsoft.Extensions.Caching.SqlServer for SQL Server distributed caching.
Configure SQL Server for Session Storage

First, create a database in the SQL Server database with the SessionDB, where we will store the session data.

Before proceeding, ensure you have a SQL Server database available. You’ll need to create a table to store session data. The dotnet sql-cache command is part of the .NET Core CLI, specifically designed for working with distributed SQL server cache. If you’re unable to find this command, it’s likely that the necessary tool is not installed on your system. To install it, you should run the following command:

dotnet tool install –global dotnet-sql-cache

The sql-cache create tool can be used to create this table. Run the following command in your terminal, replacing the placeholders with your database details. The following command creates a table named MySessions in the specified database to store session data.

dotnet sql-cache create “Data Source=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Initial Catalog=SessionDB;Integrated Security=True;TrustServerCertificate=True” dbo MySessions

Once the above command is executed successfully, the MySessions table must be created in the SessionDB database with the following structure:

In-Memory or In-Proc vs. Distributed or Out-Proc Sessions in ASP.NET Core MVC

Understanding the Table Structure:

SPONSOR AD
  • ID: This is a unique identifier for each session. It’s typically a string that represents the session key. This key is used by the ASP.NET Core application to identify and retrieve the session data for each request.
  • Value: The Value column holds the serialized session data. When your application stores any data in the session (using HttpContext.Session.SetString, SetInt32, Set, etc.), ASP.NET Core serializes this data into a binary format and stores it in this column.
  • ExpiresAtTime: This column stores the timestamp at which the session will expire. The session state middleware in ASP.NET Core checks this value to determine if the session data is still valid. If the current time is greater than the ExpiresAtTime, the session is considered expired, and the middleware will not return the stored data.
  • SlidingExpirationInSeconds: This column is used when the session is configured for sliding expiration. Sliding expiration resets the session’s expiration time to be a set amount of time from the current time, but only if the session is accessed. This value represents the amount of time (in seconds) to extend the session’s life from the current moment when a request is made. If this column is used, each time the session is accessed, the ExpiresAtTime is updated to be the current time plus the value in SlidingExpirationInSeconds.
  • AbsoluteExpiration: This column is used for an absolute expiration policy, where the session will expire at a specific point in time, regardless of whether it’s accessed. It’s an alternative to sliding expiration. This would be set to a specific point in time (timestamp), after which the session should no longer be considered valid.
Configuring Connection String:

Storing the Connection string in the AppSettings.json file. So, modify the AppSettings.json file as follows. Here, you can see we have added the ConnectionStrings section.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "EFCoreDBConnection": "Server=LAPTOP-6P5NK25R\\SQLSERVER2022DEV;Database=SessionDB;Trusted_Connection=True;TrustServerCertificate=True;"
  }
}
Step 4: Configure DbContext

Create a DbContext class for the application. So, add a class named EFCoreDBContext.cs within the Models folder and then copy and paste the following code.

using Microsoft.EntityFrameworkCore;

namespace SampleMVCWeb.Models
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext(DbContextOptions<EFCoreDbContext> options) : base(options)
        {
        }
    }
}
Configure Services for Distributed Cache

In your Program.cs file, configure Entity Framework Core, and the distributed SQL Server cache. In this configuration, replace EFCoreDbContext and EFCoreDBConnection with your specific Entity Framework Core context and connection string.

// Add Session Services to the Container.
builder.Services.AddDbContext<EFCoreDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("EFCoreDBConnection")));

//Add Distributed Sql Server Cache Service
builder.Services.AddDistributedSqlServerCache(options =>
{
    //Specify the ConnectionString, Database Schema and TableName
    options.ConnectionString = builder.Configuration.GetConnectionString("EFCoreDBConnection");
    options.SchemaName = "dbo";
    options.TableName = "MySessions";
});

//Add AddSession Service to enable Session Feature
//Adds services required for application session state.
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

Note: The AddDistributedSqlServerCache method in ASP.NET Core is used to set up a distributed cache that is backed by a SQL Server database. This method is part of the Microsoft.Extensions.DependencyInjection namespace. Distributed caching is a method of caching where the data is stored across multiple servers, which can help in maintaining consistency and performance in web applications, especially those deployed in a load-balanced, multi-server environment.

Configure Session Middleware

In the same Program.cs file, add the session middleware to the application’s request pipeline.

app.UseRouting();
app.UseAuthorization();

//Configuring Session Middleware in ASP.NET Core
//It should and must be configured after UseRouting and before MapControllerRoute
app.UseSession();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
Using Sessions in Controllers

You can now use sessions in your controllers just like you would with in-memory sessions:

using Microsoft.AspNetCore.Mvc;

namespace SampleMVCWeb.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            HttpContext.Session.SetInt32("UserId", 123456);
            HttpContext.Session.SetString("UserName", "info@dotnettutorials.net");
            return View();
        }

        public IActionResult Privacy()
        {
            var sessionUserName = HttpContext.Session.GetString("UserName");
            ViewBag.UserName = sessionUserName;

            var sessionUserId = HttpContext.Session.GetInt32("UserId");
            ViewBag.UserId = sessionUserId;
            return View();
        }
    }
}

Next, modify the Index.cshtml view as follows:

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-left">
    <h2>Index Page</h2>
</div>

Next, modify the Privacy.cshtml view as follows:

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<div class="text-left">
    <b>User Name:</b>@ViewBag.UserName
    <br />
    <b>User Id:</b> @ViewBag.UserId
</div>

Now, run the application and visit the Index action method where we are saving the session data. Now, once you access the Home Page, go to the database and check the MySession data, and you should see the following:

SPONSOR AD

Note: The AbsoluteExpiration column is not used by the default SQL Server distributed cache implementation in ASP.NET Core. This column is part of the schema for compatibility with other potential caching implementations that might use absolute expiration. However, in the default setup with ASP.NET Core and SQL Server, this column is left null and does not play a role in the expiration mechanism.

How do you delete the distributed session data from the SQL Server database?

Managing and deleting expired session data from the SQL Server database in an ASP.NET Core MVC application, especially when using distributed sessions, is important for maintaining performance and efficient data management.

SQL Server doesn’t automatically clean up expired sessions. Therefore, you need to implement a mechanism to remove old session data periodically. You can create an SQL Server Agent Job or a scheduled task that runs an SQL script to delete expired sessions. Here is an example SQL script that you could run:

DELETE FROM [YourSessionTable] WHERE ExpiresAt < GETUTCDATE();

Replace [YourSessionTable] with the name of your session table. This script deletes all sessions that have expired according to the ExpiresAt column.

Key Differences Between In-Proc and Out-Proc Sessions:
  • Location of Data: In-Proc stores data in server memory, and Out-Proc stores data in a separate system.
  • Data Persistence: Out-Proc can maintain data persistence across server restarts, whereas In-Proc cannot.
  • Resource Utilization: In-Proc uses server memory, which can be a constraint. Out-Proc uses external resources, which adds to network overhead but frees up server memory.
  • Complexity: Implementing and maintaining a distributed session state is more complex than in-memory sessions.
Choosing the Right Approach
  • Size and Scale of the Application: Small, single-server applications might benefit from the simplicity of In-Proc sessions. Large, distributed applications usually require Out-Proc sessions.
  • Session Data Criticality: Out-Proc is a better choice if losing session data is unacceptable.
  • Load Balancing Needs: If the application is load-balanced across multiple servers, Out-Proc sessions are necessary to ensure session data is available across all servers.
  • Performance Considerations: In-Proc can offer better performance but at the cost of scalability and reliability.

In the next article, I will explain the Differences Between Cookies and Sessions in ASP.NET Core MVC with Examples. In this article, I try to explain In-Memory or In-Proc and Distributed or Out-Proc Sessions in ASP.NET Core MVC with Examples. I hope you enjoy this article in the In-Memory or In-Proc and Distributed or Out-Proc Sessions in ASP.NET Core MVC.

SPONSOR AD

Leave a Reply

Your email address will not be published. Required fields are marked *