All About Sessions In ASP.NET Core

HTTP is a stateless protocol, so we need some mechanism to maintain our App State. Server Side Session has been a way to maintain our state on the server side. In this article we'll see what differences ASP.NET Core has introduced regarding SESSION.

We'll quickly discuss how we used to use Sessions before ASP.NET Core and then we'll see how to access Sessions in ASP.NET Core.
 

Session In Pre-ASP.NET Core era

  • You get Session functionality by default (without adding any package)
  • Previously, you would have accessed Session by -

    • Session variable in your Controllers/Forms
    • System.Web.HttpContext.Current.Session in places where you don't have direct access to the Session variable.

  • Anything you store in session is stored as Object. You store values in Key/Value format.
    1. Session["mydata"] = 10;   
    Or to access on those places where Session is not available (e.g. Non-Controller classes)
    1. System.Web.HttpContext.Current.Session["mydata"] = 10;   
  • Quite difficult to mock Session Object for Unit Testing

Session in ASP.NET Core 2.2

  1. Now, Session is not available by default.
  2. You need to add the following package. Meta package by default provides you this.
    1. <PackageReference Include="Microsoft.AspNetCore.Session" Version="2.2.0" />  
  3. In Startup.ConfigureServices, you need to add the following to register services with DI Container.
    1. services.AddDistributedMemoryCache();//To Store session in Memory, This is default implementation of IDistributedCache    
    2. services.AddSession();  
  4. In Startup.Configure, you need to add the following (before UseMVC) to add Session Middleware.
    1. app.UseCookiePolicy();      
    2. app.UseSession();      
    3. app.UseMvc(routes =>    
  5. Make sure the following is also there (It is added by default when you use ASP.NET Core MVC Template).
    1. app.UseCookiePolicy();   
  6. ASP.NET Core 2.2 onwards adds Cookie Consent (true) in the Startup file. When an application runs, the user needs to accept Cookie Consent on screen. When the user accepts the policy on the page, it creates a consent cookie. It is to follow GDPR and to give control to the user if the user wants to store cookies from a site or not. If the user doesn't accept that, Session does not work because Session requires a cookie to send/receive session Id. You may face this issue while working with ASP.NET Core MVC default template.

How to access Session in Controller?

 
You will notice that you don't have "Session" variable available now. Controller now has a property "HttpContext" which has "Session" variable. So, you can access session in controller by using the following code.
  1. var a = this.HttpContext.Session.GetString("login");    
  2. HttpContext.Session.SetString("login", dto.Login);  

How to access Session in Non-Controller class?

 
Now, you don't have System.Web.HttpContext.Current.Session in ASP.NET Core. To access session in non-controller class -
  • First, register the following service in Startup.ConfigureServices;
    1. services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();  
  • Now, register a class (example - TestManager) where you want to access the Session in Startup.ConfigureServices;
    1. services.AddScoped<TestManager>();  
    Note
    You may use AddTransient or AddSingleton according to your logic.

  • Now, in TestManager class, add the following code.
    1. private readonly IHttpContextAccessor _httpContextAccessor;    
    2. private readonly ISession _session;    
    3. public TestManager(IHttpContextAccessor httpContextAccessor)    
    4.    {    
    5.         _httpContextAccessor = httpContextAccessor;    
    6.         _session = _httpContextAccessor.HttpContext.Session;    
    7.     }  
The above code is receiving IHttpContextAccessor object through dependency injection and then, it is storing Sessions in a local variable. 
 

How to access Session in View file?

 
Add the following at the top of your View file.
  1. @using Microsoft.AspNetCore.Http    
  2. @inject IHttpContextAccessor httpContextAccessor   
Then, you may access the Session variable in your View like following.
  1. @httpContextAccessor.HttpContext.Session.GetString("login")   

What else is changed regarding Session?

  • Session is non-locking now.
  • A session is not created until you have at least one value in it
  • You need to use functions to get & set data. Array syntax is not supported now.
  • Now, ISession only provides Get & Set method which takes & returns data in Byte Array format.
  • If you want to store data in the String format, you may add the following in your file and use extension methods.
    1. using Microsoft.AspNetCore.Http;   
    It exposes the new extension methods.
    1. SetInt32    
    2. GetInt32    
    3. SetString    
    4. GetString    
    Under the hood, these covert the data into bytes.

  • You may also write your own extension methods. For example, the following Extension Methods help you store & retrieve any complex type.
    1. public static class SessionExtensions        
    2.     {        
    3.         public static void Set<T>(this ISession session, string key, T value)        
    4.         {        
    5.             session.Set<(key, JsonConvert.SerializeObject(value));        
    6.         }        
    7.         
    8.         public static T GetObject<T>(this ISession session, string key)        
    9.         {        
    10.             var value = session.GetString(key);        
    11.             return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);        
    12.         }        
    13.     }   
In the next article, we'll learn about SESSION Wrapper Design Pattern.
 

Summary

 
Session concepts are similar to what we've seen in earlier .NET Frameworks. The real difference is that now, it is cleaner & more flexible to use.