ISession provides access to the session data associated with an ASP.NET Core request through HttpContext.Session. Data is addressed by string keys. The session middleware handles the session cookie and loads data from the cache; request code reads and updates values through the interface. section 16.3.2
To use session data in an endpoint:
- Register a cache and session services, then call UseSession before mapping endpoints that access HttpContext.Session. section 16.3.2
- Read a value, supply a default when it is absent, and write the updated value before sending the response. A first request has no stored value. section 16.3.2
- Optionally call CommitAsync before writing the response. It exposes cache-write failures that otherwise may go unreported. section 16.3.2
A counter that survives requests
At /session, read GetInt32("counter1") ?? 0, increment it, and store it with SetInt32("counter1", counter1). Repeat requests to observe the count increase. Configure AddDistributedMemoryCache, AddSession, and UseSession before the endpoint. section 16.3.2
ISession also supports removing one key with Remove, clearing all session data with Clear, enumerating Keys, and checking IsAvailable. Its simple stored values do not directly accommodate a Cart object. For a shopping cart, extension methods serialize the object as JSON into a string with SetString and reconstruct it with GetString and JsonSerializer.Deserialize. A Razor Page can then read the cart from HttpContext.Session on a later request. section 16.3.2 section 8.2.5
Listing 16.8 Using session data in the Program.cs file in the Platform folder
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(opts => {
opts.IdleTimeout = TimeSpan.FromMinutes(30);
opts.Cookie.IsEssential = true;
});
var app = builder.Build();
app.UseSession();
app.MapGet("/session", async context => {
int counter1 = (context.Session.GetInt32("counter1") ?? 0) + 1;
int counter2 = (context.Session.GetInt32("counter2") ?? 0) + 1;
context.Session.SetInt32("counter1", counter1);
context.Session.SetInt32("counter2", counter2);
await context.Session.CommitAsync();
await context.Response
.WriteAsync($"Counter1: {counter1}, Counter2: {counter2}");
});
app.MapFallback(async context =>
await context.Response.WriteAsync("Hello World!"));
app.Run();
The complete Program.cs example shows service registration, middleware order, a session-backed endpoint, and CommitAsync before the response. section 16.3.2
Listing 8.23 The SessionExtensions.cs file in the SportsStore/Infrastructure folder
using System.Text.Json;
namespace SportsStore.Infrastructure {
public static class SessionExtensions {
public static void SetJson(this ISession session,
string key, object value) {
session.SetString(key, JsonSerializer.Serialize(value));
}
public static T? GetJson<T>(this ISession session, string key) {
var sessionData = session.GetString(key);
return sessionData == null
? default(T) : JsonSerializer.Deserialize<T>(sessionData);
}
}
}
The extension-method listing shows how a complex object is serialized to a session string and deserialized on retrieval. section 8.2.5
