top of page

Session State in ASP.NET Core



What is Session State in ASP.NET Core?

Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Session state uses a store maintained by the app to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data. The site should continue to function without the session data. Critical application data should be stored in the user database and cached in session only as a performance optimization.


Session isn't supported in SignalR apps because a SignalR Hub may execute independent of an HTTP context. For example, this can occur when a long polling request is held open by a hub beyond the lifetime of the request's HTTP context.


ASP.NET Core maintains session state by providing a cookie to the client that contains a session ID. The cookie session ID:

  • Is sent to the app with each request.

  • Is used by the app to fetch the session data.


Session state exhibits the following behaviors:

  • The session cookie is specific to the browser. Sessions aren't shared across browsers.

  • Session cookies are deleted when the browser session ends.

  • If a cookie is received for an expired session, a new session is created that uses the same session cookie.

  • Empty sessions aren't retained. The session must have at least one value set to persist the session across requests. When a session isn't retained, a new session ID is generated for each new request.

  • The app retains a session for a limited time after the last request. The app either sets the session timeout or uses the default value of 20 minutes. Session state is ideal for storing user data:

    • That's specific to a particular session.

    • Where the data doesn't require permanent storage across sessions.

  • Session data is deleted either when the ISession.Clear implementation is called or when the session expires.

  • There's no default mechanism to inform app code that a client browser has been closed or when the session cookie is deleted or expired on the client.

  • Session state cookies aren't marked essential by default. Session state isn't functional unless tracking is permitted by the site visitor. For more information, see General Data Protection Regulation (GDPR) support in ASP.NET Core.


Working with Session State in ASP.NET Core

Sessions are of two types:

  1. In-Proc or In-memory - If our session is in-memory and our application is hosted on Web-Farm environment, we need to use sticky sessions to tie each session to a specific Server

  2. Out-Proc or Distributed session - session does not require sticky sessions and they are the most preferred way to use sessions in our application.


Microsoft.AspNetCore.Session package provides middleware to manage the sessions in ASP.NET Core. To use session in our Application, we need to add this package as a dependency in project.json file.

The next step is to configure session in Startup class. We need to call “AddSession” method in ConfigureServices method of startup class. The “AddSession” method has one overload method, which accepts various session options such as Idle Timeout, Cookie Name and Cookie Domain etc. If we do not pass the session options, the system will take the default options. Now, we need to call “UseSession” method in Configure method of startup class. This method enables the session for the Application.


Startup.cs

using System;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Http;  
using Microsoft.Extensions.DependencyInjection;  
  
namespace WebApplication {  
    public class Startup {  
        public void Configure(IApplicationBuilder app)  
        {  
            app.UseSession();  
            app.UseMvc();  
            app.Run(context => {  
                return context.Response.WriteAsync(“Hello Readers!”);  
            });  
        }  
  
        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddMvc();  
            services.AddSession(options => {   
                options.IdleTimeout = TimeSpan.FromMinutes(30);   
            });  
        }       
    }  
}  

It is important to call “UseSession” method before the “UseMvc” method in Configure method of startup class. If we call “UseMvc” method before “UseSession” method, the system will throw an exception.


How to access the session

We can use session from HttpContext, once it is installed and configured. To use session in controller class, we need to reference “Microsoft.AspNet.Http” in controller. There are three methods that enables us to set the session value, which are Set, SetInt32 and SetString. The “Set” method accepts byte array as an argument. The SetInt32 and SetString method are the extension methods of Set and they internally cast byte array to int and string respectively. Same as there are three methods that are used to retrieve the value from the session: Get, GetInt32 and GetString. The Get method returns byte of arrays. The main reason behind storing bytes array is to make sure that session values are serializable for the storage on remote Servers. Apart from int and string, we need to serialize to byte array to store it in session.


Example In the example given below, I have set my name into session in first request and retrieved the session value in another request.

using Microsoft.AspNetCore.Http;  
using Microsoft.AspNetCore.Mvc;  
  
public class HomeController : Controller  
{  
  
    [Route(“home/index”)]  
    public IActionResult Index()  
    {  
        HttpContext.Session.se.SetString(“name”,”Jignesh Trivedi”);  
        return View();  
    }  
    [Route(“home/GetSessionData”)]  
    public IActionResult GetSessionData()  
    {  
        ViewBag.data = HttpContext.Session.GetString(“name”);;  
        return View();  
    }  
}  


Custom Session Extension methods

As discussed earlier, there are two extension methods to get the data from session and set the data to session are available, namely GetInt32 and GetString, SetInt32 and SetString. Similarly, we can add our custom extension methods to get and set the value in session.


Created an extension method to set double value to session and get double value from session.

using System;  
using Microsoft.AspNetCore.Http;  
public static class SessionExtensions  
{  
    public static double? GetDouble(this ISession session, string key)  
    {  
        var data = session.Get(key);  
        if (data == null)  
        {  
            return null;  
        }  
        return BitConverter.ToDouble(data, 0);  
    }   
  
    public static void SetDouble(this ISession session, string key, double value)  
    {  
        session.Set(key, BitConverter.GetBytes(value));  
    }  
}  

Usage of the extension method

using Microsoft.AspNetCore.Http;  
using Microsoft.AspNetCore.Mvc;  
public class HomeController : Controller  
{  
  
    [Route(“home/index”)]  
    public IActionResult Index()  
    {  
        HttpContext.Session.SetString(“name”,”Jignesh Trivedi”);  
        HttpContext.Session.SetDouble(“Percentage”,75.56);  
        return View();  
    }  
    [Route(“home/GetSessionData”)]  
    public IActionResult GetSessionData()  
    {  
        ViewBag.data = HttpContext.Session.GetString(“name”);  
        ViewBag.Percent = HttpContext.Session.GetDouble(“Percentage”);  
        return View();  
    }  
}  

Store Complex Data in to Session

As we are aware, session is able to store only byte of an array. Compared to the previous version, ASP.NET Core does not perform any operation such as serialization/ de-serialization on the values stored in session. Here, I am converting the complex object into JSON and store it as a string. Later, I am retrieving it as a string and de-serialize to original object.


The extension method for set and get complex object to session.

using System;  
using Microsoft.AspNetCore.Http;  
using Newtonsoft.Json;  
  
public static class SessionExtensions  
{  
    public static T GetComplexData<T>(this ISession session, string key)  
    {  
        var data = session.GetString(key);  
        if (data == null)  
        {  
            return default(T);  
        }  
        return JsonConvert.DeserializeObject<T>(data);  
    }   
  
    public static void SetComplexData(this ISession session, string key, object value)  
    {  
        session.SetString(key, JsonConvert.SerializeObject(value));  
    }  
}  

Usage of the extension method

In the following example, created one public class and within controller action method, created the instance of the class, stored some data and sent it for storing in session. Similarly, created one action method to retrieve the complex data from session.

public class User   
{  
    public string Name { get; set; }  
    public double Percentage { get; set; }  
}  

Action method

[Route(“home/SetComplexData”)]  
public IActionResult SetComplexData()  
{  
    User user = new User();  
    user.Name = “Jignesh Trivedi”;  
    user.Percentage = 75.45;             
      
    HttpContext.Session.SetComplexData(“UserData”, user);  
    return View(“index”);  
}  
[Route(“home/GetComplexData”)]  
public IActionResult GetComplexData()  
{  
    ViewBag.data = HttpContext.Session.GetComplexData<User>(“UserData”);  
    return View();  
}  

Configure session state

The Microsoft.AspNetCore.Session package:

  • Is included implicitly by the framework.

  • Provides middleware for managing session state.

To enable the session middleware, Program.cs must contain:

  • Any of the IDistributedCache memory caches. The IDistributedCache implementation is used as a backing store for session. For more information, see Distributed caching in ASP.NET Core.

  • A call to AddSession

  • A call to UseSession

The following code shows how to set up the in-memory session provider with a default in-memory implementation of IDistributedCache:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();
app.UseSession();
app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

The preceding code sets a short timeout to simplify testing. The order of middleware is important. Call UseSession after UseRouting and before MapRazorPages and MapDefaultControllerRoute . See Middleware Ordering.


HttpContext.Session is available after session state is configured. HttpContext.Session can't be accessed before UseSession has been called.


A new session with a new session cookie can't be created after the app has begun writing to the response stream. The exception is recorded in the web server log and not displayed in the browser.




The Tech Platform

0 comments
bottom of page