Sessions in ASP.NET Core MVC

Sessions in ASP.NET Core MVC

In this article, I am going to discuss Sessions in ASP.NET Core MVC Applications with Examples. Please read our previous article, where we discussed Cookies in ASP.NET Core MVC. Sessions are one of the several ways to manage state in an ASP.NET Core application. The HTTP protocol is, by default, stateless. But sometimes, it’s essential to hold user data while users are browsing our website. This data can help to remember their recent actions. For example, on an e-commerce website, this data can help to store products in a shopping cart.

What are Sessions in ASP.NET Core MVC?

In ASP.NET Core MVC, sessions are a mechanism for storing and managing user-specific data on the server side across multiple HTTP requests for a given session. A session provides a way to maintain a state for a user throughout their interaction with a web application, allowing you to store and retrieve data that is associated with a particular user’s session.

Sessions are particularly useful when you need to store data that should be available across different pages or requests for a specific user without relying on cookies or query parameters. Unlike cookies, which are stored on the client-side, session data is stored on the server side, enhancing security and reducing the risk of exposing sensitive information.

How Does Session Work in Web Application?

A session is responsible for storing user data in the web server when browsing a web application. In general, web applications operate on the stateless HTTP Protocol, where each HTTP request is independent. The web server is unable to store anything on the server related to the client’s request. That means the server lacks the ability to retain values used in previous requests.

To address this, ASP.NET Core provides the Session feature, which enables storing and retrieving user data on the server side. The Session stores data in the Web Server Cache (To store the Session Data, the Server uses Temporary Caching Mechanism) by creating the SessionId as the key. Then the same SessionId, it sends to the Web Browser using Cookies. That means the SessionId is stored as a cookie on the client machine, and these SessionId cookies are sent with every request from client to server. For a better understanding, please have a look at the following diagram.

How Does Session work in Web Application?

Session work as Follows:
  1. First, the client (Web Browser) will send the HTTP Request to the Server.
  2. Once the server receives the request, it will process the request and generate the response. Along with the generated response, it will create a SessionId and then send that SessionId in the Response header using the cookie. At the same time, the SessionId will also store on the server cache as a key with the required values. If this is not clear at the moment, don’t worry. Once we explain the example, you will understand,
  3. Once the client receives the response, from the next request onwards (as long as the session is not expired), the client will send the HTTP Request along with the cookie (cookie containing the SessionId) in the request header.
  4. Once the server receives the request, it will check the cookie, get the SessionId from the Cookie, fetch the data from the server cache based on the SessionId and accordingly process the request.

Note: Each browser has a unique SessionId that is deleted at the end of the session and not shared with other browsers. The default session timeout is 20 minutes but can be configured based on business requirements.

Two types of sessions are available: In-Memory or In-Proc and Distributed or Out-Proc sessions. In the case of In-Memory sessions, hosting the application on a web farm requires linking each session to a specific server. On the other hand, applications often prefer the Out-Proc session, which does not require linked sessions.

How To Use Session in ASP.NET Core?

The package Microsoft.AspNetCore.Session offers a middleware component for managing the Session in ASP.NET Core Web Application. The Microsoft.AspNetCore.Session package:

  1. It is included implicitly by the Framework.
  2. Provides Middleware Component for Managing Session State.

To enable the Session Middleware Component in ASP.NET Core Web Application, the Main method of the Program class must contain the followings:

  1. Any of the IDistributedCache Memory Cache Service. The IDistributedCache implementation is used to store user data in the server by creating a SessionId as the key. We will discuss Distributed Caching in detail in our upcoming articles.
  2. A call to the AddSession Service method where we need to configure the session time out, whether the session is essential or not, and whether we want to access the session using HTTP only or not.
  3. A call to the UseSession Middleware component to register the session into the application processing pipeline. It should be registered after the Routing and before the MVC Middleware component. This is because we want the session middleware component to be executed before executing the action method.

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

Sessions in ASP.NET Core MVC Applications with Examples

The above code sets a short timeout session (10 seconds) to simplify testing. So, if we stay idle for 10 seconds, the session will be expired. HttpOnly Indicates whether a cookie is accessible by client-side script, and we set its value to true means you cannot access using client-side JavaScript. The IsEssential property Indicates if this cookie is essential for the application to function correctly. If true, then consent policy checks may be bypassed. The default value is false. And here, we set this value to true.

The order of middleware components is important. We need to call the UseSession Middleware Component after the UseRouting and before the MapControllerRoute component in ASP.NET Core MVC Web Application.

  1. HttpContext.Session is only available after the session state is configured.
  2. HttpContext.Session can’t be accessed before UseSession has been called.
Session Options:
  1. Cookie: It determines the settings used to create the cookie. The name defaults to SessionDefaults.CookieName (.AspNetCore.Session). Path defaults to SessionDefaults.CookiePath (/). HttpOnly defaults to true. IsEssential defaults to false.
  2. IdleTimeout: The app uses the IdleTimeout property to determine how long a session can be idle before its contents in the server’s cache are cleared. This property is independent of the cookie expiration. Each request that passes through the Session Middleware resets the timeout. The default is 20 minutes.
  3. IOTimeout: The maximum amount of time allowed to load a session from the store or to commit it back to the store. This setting may only apply to asynchronous operations. This timeout can be disabled using InfiniteTimeSpan. The default is 1 minute.

The session uses a cookie to track and identify requests from a single browser. By default, this cookie is named “.AspNetCore.Session” and uses a path of /. Because the cookie default doesn’t specify a domain, it isn’t made available to the client-side script on the page (because HttpOnly defaults to true).

Sessions in ASP.NET Core MVC Applications with Examples

So, modify the Main method of the Program class as follows:

namespace SampleMVCWeb
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

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

            //Configuring Session Services in ASP.NET Core
            builder.Services.AddDistributedMemoryCache();
            builder.Services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(10);
                options.Cookie.Name = ".MySampleMVCWeb.Session";
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            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?}");

            app.Run();
        }
    }
}

Important Note: Session state is non-locking. If two requests simultaneously attempt to modify the contents of a session, the last request overrides the first. The session is implemented as a coherent session, which means that all the contents are stored together. When two requests seek to modify different session values, the last request may override session changes made by the first.

Set and Get Session Values in ASP.NET Core MVC

The ISession implementation provides extension methods and we can use these extension methods to set and retrieve integer and string values from the Session state, which can be accessed from a Razor Pages PageModel class or from an MVC Controller class using HttpContext.SessionThe following is the list of ISession extension methods:

  1. Get(ISession, String)
  2. GetInt32(ISession, String)
  3. GetString(ISession, String)
  4. SetInt32(ISession, String, Int32)
  5. SetString(ISession, String, String)

Note: Don’t store sensitive data in the session state. The user might not close the browser and clear the session cookie. Some browsers maintain valid session cookies across browser windows. A session might not be restricted to a single user. The next user might continue to browse the app with the same session cookie.

Modifying the Home Controller:

Next, modify the HomeController as follows. As you can see, we have created two const variables to store the session keys. Within the Index Action method, we are storing the user data in the session object. Further, if you notice, we are accessing the session data from the About action method.

using Microsoft.AspNetCore.Mvc;
namespace SampleMVCWeb.Controllers
{
    public class HomeController : Controller
    {
        const string SessionUserId = "_UserId";
        const string SessionUserName = "_UserName";
        public IActionResult Index()
        {
            //Let assume the User is logged in and we need to store the user information in the session
            //Storing Data into Session using SetString and SetInt32 method
            HttpContext.Session.SetString(SessionUserName, "pranaya@dotnettutotials.net");
            HttpContext.Session.SetInt32(SessionUserId, 1234567);
            return View();
        }

        public string About()
        {
            //Accessing the Session Data inside a Method
            string? UserName = HttpContext.Session.GetString(SessionUserName);
            int? UserId = HttpContext.Session.GetInt32(SessionUserId);

            string Message = $"UserName: {UserName}, UserId: {UserId}";
            return Message;
        }

        public IActionResult Privacy()
        {
            return View();
        }
    }
}

Note: After 10 seconds, the cookie is expired, and you will not get the data once the cookie is expired.

How to Access the Session Object in a View?

In order to use the Session inside a View, we need to inject the IHttpContextAccessor object into our view, and then we need to use the IHttpContextAccessor object to get the HttpContext and Session. For this, we need to add the following two statements in our view. The first statement adds the namespace and the second statement injects the IHttpContextAccessor, and using this HttpContextAccessor; we can access the HttpContext and Session object.
@using Microsoft.AspNetCore.Http;
@inject IHttpContextAccessor HttpContextAccessor

Modifying the Index.cshtml view:
@using Microsoft.AspNetCore.Http;
@inject IHttpContextAccessor HttpContextAccessor

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

<div class="text-left">
    <b>User Name:</b> @HttpContextAccessor?.HttpContext?.Session.GetString("_UserName")
    <br />
    <b>User Id:</b> @HttpContextAccessor?.HttpContext?.Session.GetInt32("_UserId")
</div>
Modifying the Privacy.cshtml view:
@using Microsoft.AspNetCore.Http;
@inject IHttpContextAccessor HttpContextAccessor

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

<div class="text-left">
    <b>User Name:</b> @HttpContextAccessor?.HttpContext?.Session.GetString("_UserName")
    <br />
    <b>User Id:</b> @HttpContextAccessor?.HttpContext?.Session.GetInt32("_UserId")
</div>

With the above changes in place, you will get the following exception if you run the application. This is because we are using the HttpContextAccessor service, but we have not yet configured this service into the built-in IOC container.

Sessions in ASP.NET Core MVC Applications with Examples

Now, we need to configure the HttpContextAccessor service within the Main method of the Program class. The following piece of code does the same.

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

So, modify the Main method of the Program class as follows:

namespace SampleMVCWeb
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();
            //Adding the IHttpContextAccessor servive to the Dependency Injection IOC Container
            builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            //Configuring Session Services in ASP.NET Core
            builder.Services.AddDistributedMemoryCache();
            builder.Services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(10);
                options.Cookie.Name = ".MySampleMVCWeb.Session";
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            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?}");

            app.Run();
        }
    }
}

Now, run the application, and by default, it will execute the Index Action Method of Home Controller and set the session values, and then, it renders the Index view where you can see the session data as shown in the image below.

Sessions in ASP.NET Core MVC Applications with Examples

When it returns the response to the client (Web Browser), the Web Server also includes the generated SessionId in the response header using the Set-Cookie. To confirm this, open a different web browser, open the developer tool, and then issue a request to the Index action method. Then go to the Network tab, inspect the request, and go to the Response header, and you will see the Set-Cookie property is there where the web server sends the SessionId and its unique value. This SessionId value is going to be unique per session.

Sessions in ASP.NET Core MVC Applications with Examples

From the next HTTP Request onwards, the Client (Browser) will send the SessionId in the request header using Cookie. Now, within 10 seconds, if you visit the Privacy page, it will also render the session data, as shown in the image below.

Sessions in ASP.NET Core MVC Applications with Examples

If you check the Network tab and inspect the request, you will see that one cookie is being sent from the client to the web server using the Request header, as shown in the image below. And this happens in each and every request from the client to the server as long as the session is not expired.

Sessions in ASP.NET Core MVC Applications with Examples

Now, again within 10 seconds, if you visit the About page, it will also render the session data as shown in the image below.

Sessions in ASP.NET Core MVC Applications with Examples

Now, if you visit the Privacy page (Not the Index page where we store the session data) after 10 seconds, you will not get the session data as shown in the image below.

Sessions in ASP.NET Core MVC Applications with Examples

In this case, it is also sending the cookie in the HTTP request header, but it is expired. If you want, access the Index Action method, reset the Session timeout, and then the same SessionId will be used.

Advantages and Disadvantages of using Sessions in ASP.NET Core MVC

Using sessions in ASP.NET Core MVC provides a way to maintain user-specific data across multiple requests and interactions. Sessions have both advantages and disadvantages that you should consider when deciding whether to use sessions in your application.

Advantages of Using Sessions in ASP.NET Core MVC:
  1. User State Management: Sessions allow you to manage and maintain user-specific data throughout their interactions with your application. This is useful for scenarios like maintaining user authentication status, shopping carts, and user preferences.
  2. Server-Side Storage: Session data is stored on the server, reducing the risk of exposing sensitive information to clients or tampering.
  3. Flexibility: Sessions can store various types of data, including complex objects and custom data structures, providing flexibility in the types of information you can manage.
  4. Large Data: Sessions are not as limited in size as cookies, allowing you to store larger amounts of data.
  5. Centralized Management: ASP.NET Core provides built-in mechanisms for managing sessions, including configuration options and different session storage providers.
  6. Scalability: ASP.NET Core supports various session storage options, such as in-memory storage, distributed caches, and external databases, allowing you to scale your application as needed.
  7. Security: Session data is less susceptible to tampering or attacks compared to client-side storage options like cookies.
  8. Customization: You can configure session behavior and storage based on your application’s requirements, such as setting session timeouts or using distributed caching.
Disadvantages of Using Sessions in ASP.NET Core MVC:
  1. Server Resources: Storing session data on the server consumes server memory and resources, potentially impacting the scalability and performance of your application.
  2. Persistence: Session data is typically stored in memory, which means it may not persist across application restarts or server failures.
  3. Latency: Using session storage mechanisms like distributed caches may introduce additional latency due to data retrieval and network communication.
  4. Session ID Management: Proper session ID management is essential to prevent session fixation and session hijacking vulnerabilities.
  5. Complexity: Implementing and managing sessions can introduce complexity to your application architecture, particularly when using distributed session storage.
  6. Session Cloning: Depending on the session storage mechanism, session data might be cloned for each request, leading to performance overhead and potential memory usage concerns.
  7. Data Serialization: Session data often needs to be serialized and deserialized, which can impact performance, especially for complex objects.
  8. Regulations: Depending on the type of data stored in sessions, you may need to consider data protection regulations and ensure proper handling of sensitive user information.

When deciding whether to use sessions in ASP.NET Core MVC, carefully evaluate your application’s scalability needs, data persistence requirements, and security considerations. Sessions are a powerful tool for managing user-specific data, but they should be used thoughtfully and optimized based on your application’s specific use cases and constraints.

When to use Sessions in ASP.NET Core MVC?

Sessions in ASP.NET Core MVC provide a mechanism for maintaining user-specific data across multiple requests and interactions. They can be beneficial in various scenarios where you must manage user states and provide a personalized experience. Here are some situations where using sessions is appropriate:

  1. User Authentication and Authorization: Sessions are commonly used to manage user authentication and authorization status. You can store information about the user’s identity and roles in a session to maintain their logged-in state.
  2. User Preferences: Sessions can be used to store and manage user preferences, such as language settings, theme choices, or display preferences. This allows you to provide a customized experience for each user.
  3. Shopping Carts: Sessions are often employed to manage shopping cart data. You can store information about items added to the cart and their quantities, ensuring that the cart contents are retained between page views and interactions.
  4. Form Data Persistence: Sessions can be used to temporarily store form data between multiple steps of a multi-page process. This is useful for scenarios like multi-step forms or wizards.
  5. User Activity Tracking: Sessions can help track user interactions and behavior on a website. This data can be used for analytics, generating insights about user engagement, and understanding user journeys.
  6. Temporary Data: Sessions can be used to store temporary data that needs to persist for a short period, such as alerts, notifications, or messages.
  7. User-Specific Data: When you need to maintain user-specific data that doesn’t belong to a database, sessions provide a convenient way to store and access this information.
  8. Cross-Request Communication: Sessions allow you to share data between different requests from the same user, enabling interactions between different parts of your application.
  9. Caching: Sessions can be used for caching frequently accessed data to improve performance and reduce the need for repeated data retrieval.
  10. Single Sign-On (SSO): Sessions can be used for implementing single sign-on across multiple applications, allowing users to authenticate once and access multiple services without repeated logins.
  11. User Tracking and Personalization: Sessions can be used to track user behavior and interactions, enabling personalized content recommendations and user-specific features.
  12. Game State: For web-based games, sessions can be used to store and manage game state information for each player.

It’s important to consider the following factors when deciding to use sessions:

  1. Server Resources: Sessions consume server memory and resources. Evaluate the impact of session data on your application’s performance and scalability.
  2. Data Persistence: Sessions are typically stored in memory, which means session data may not persist across application restarts or server failures. Consider using distributed session storage for scenarios requiring data persistence.
  3. Session Management: Proper session management, including session ID handling and expiration, is crucial to prevent security vulnerabilities.
  4. Data Protection Regulations: Depending on the data stored in sessions, you may need to adhere to data protection regulations and ensure proper handling of sensitive user information.
  5. Scalability: Sessions can affect the scalability of your application, especially if you’re using in-memory session storage. Consider using distributed caches or external data stores for improved scalability.

In summary, sessions are a powerful tool for managing user-specific data and states in ASP.NET Core MVC applications. They should be used judiciously based on your application’s specific requirements and constraints to provide a seamless and personalized user experience.

Differences Between Cookies and Sessions in ASP.NET Core MVC

Cookies and sessions are mechanisms for State Management in ASP.NET Core MVC Applications, but they have distinct differences in where data is stored, how long it persists, and how it’s accessed. Here’s a comparison of cookies and sessions in the ASP.NET Core MVC Web Application:

Cookies:
  1. Storage Location: Cookies are stored on the client side in the user’s browser.
  2. Size Limitation: Cookies have a size limitation (usually around 4KB per cookie), which restricts the amount of data that can be stored.
  3. Persistence: Cookies can be either persistent (stored beyond the current browser session) or session-based (deleted when the browser is closed).
  4. Lifetime: Cookies have an expiration date, after which the browser automatically deletes them if they are not set to be persistent.
  5. Data Security: If not properly secured, cookies can be vulnerable to tampering and cross-site scripting (XSS) attacks.
  6. Data Transfer: Cookies are included with every HTTP request to the server, increasing network traffic.
  7. Usage: Cookies are often used for maintaining user authentication, user preferences, tracking user interactions, and providing personalized experiences.
  8. Example Usage: Remembering a user’s login status, storing shopping cart items, and saving user preferences.
Sessions:
  1. Storage Location: Session data is stored on the server side.
  2. Size Limitation: Sessions can store more data than cookies, although practical limits may still exist.
  3. Persistence: Sessions can be configured for different levels of persistence, including in-memory storage (not persistent across application restarts) and distributed storage (persistent and scalable across servers).
  4. Lifetime: Sessions have a configurable timeout, after which the session data is considered expired and may be discarded.
  5. Data Security: Session data is stored on the server, making it less vulnerable to client-side attacks. Proper session ID management is crucial to prevent session fixation and hijacking.
  6. Data Transfer: Only a session ID (usually stored in a cookie) is transferred between the client and the server, reducing data transfer compared to cookies.
  7. Usage: Sessions are often used for user authentication, maintaining user-specific states, managing shopping carts, and storing temporary data.
  8. Example Usage: Storing user authentication status, managing shopping cart items, and maintaining user-specific preferences.
Considerations:
  1. Storage Location: Cookies are stored on the client side, making them accessible to the user and potentially vulnerable to tampering. Sessions are stored on the server side, providing better security for sensitive data.
  2. Data Size: Cookies have size limitations, whereas sessions can store larger amounts of data.
  3. Network Traffic: Cookies are included in every HTTP request, leading to increased network traffic. Sessions involve fewer data transfers.
  4. Security: Sessions are generally more secure as sensitive data is stored on the server side. Properly secure cookies to mitigate security risks.
  5. Persistence: Sessions can be configured for different levels of persistence, including non-persistent in-memory storage and distributed persistent storage.

In summary, cookies are suitable for smaller amounts of data that need to persist on the client side, while sessions are a more secure and flexible option for managing user-specific data on the server side. The choice between cookies and sessions depends on your application’s requirements, data sensitivity, and performance considerations.

In this article, I try to explain Sessions in ASP.NET Core MVC Applications with Examples. I hope you enjoy this Session in the ASP.NET Core MVC Application article.

2 thoughts on “Sessions in ASP.NET Core MVC”

Leave a Reply

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