What is the session state?
Session state is a feature provided by .net Core in which you can store and retrieve values server-side for a user browsing your site. Session state was often used quite extensively in ASP.NET apps but was problematic primarily performance and scalability.
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.
You should think of it more like a per-user cache. From a technical point of view, session state in ASP.NET Core requires two separate parts:
- A cookie. Used to assign a unique identifier (the session ID) to a user.
- A distributed cache. Used to store items associated with a given session ID.
Session uses a cookie to track and identify requests from a single browser. By default, this cookie is named .AspNetCore.Session
, and it 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
).
Session state exhibits the following behaviors:
- The session cookie is specific to the browser, not per logged-in user. 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.
Using session state in an ASP.NET Core
Session state is not configured by default, so you need to add the required services. Update ConfigureServices
in Startup.cs to add the session services. By default, ASP.NET Core will use an in-memory session store, which is fine for testing purposes, but will need to be updated for a production environment.
You also need to add the session middleware to your pipeline.
To enable the session middleware, Startup
must contain:
- Any of the IDistributedCache memory caches. The
IDistributedCache
implementation is used as a backing store for session. - A call to AddSession in
ConfigureServices
.
//add service to the container.
services.AddSession();
- A call to UseSession in
Configure
.CallUseSession
afterUseRouting
and beforeUseEndpoints
app.UseSession();
How to set and get value from session?
You can now find the session object by using HttpContext.Session
. HttpContext is just the current HttpContext exposed to you by the Controller class.It’s pretty easy here, just use one of the Set()
methods to store your data and one of the Get()
methods to retrieve it.
//Setting the session value
HttpContext.Session.SetString("Session Variable Name","Value");
//Getting the session value
HttpContext.Session.GetString("Session Variable Name");
All session data must be serialized to enable a distributed cache scenario, even when using the in-memory cache. String and integer serializers are provided by the extension methods of ISession.
How do I store a complex object?
I’ve got you covered here too. Here’s a quick JSON storage extension to let you store complex objects nice and simple.
public static class SessionExtensions
{
public static void SetObjectAsJson(this ISession session, string key, object value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
} public static T GetObjectFromJson<T>(this ISession session, string key)
{
var value = session.GetString(key); return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
}
Now you can store your complex objects like so:
var myComplexObject = new MyClass();
HttpContext.Session.SetObjectAsJson("Test", myComplexObject);
and retrieve them just as easily:
var myComplexObject = HttpContext.Session.GetObjectFromJson<MyClass>("Test");
Note:- Session state is non-locking. If two requests simultaneously attempt to modify the contents of a session, the last request overrides the first. 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.