Problem
How to store data in session state using ASP.NET Core.
Solution
Using an empty project from a previous post, amend Startup class ConfigureServicee() method, add services for session and its backing store,
- public void ConfigureServices(
- IServiceCollection services)
- {
- services.AddDistributedMemoryCache();
- services.AddSession();
- }
Add the session middleware in Configure() method,
- public void Configure(
- IApplicationBuilder app,
- IHostingEnvironment env)
- {
- app.UseSession();
-
- app.Use(async (context, next) =>
- {
- context.Session.SetString("GreetingMessage", "Hello Session State");
- await next();
- });
-
- app.Run(async (context) =>
- {
- var message = context.Session.GetString("GreetingMessage");
- await context.Response.WriteAsync($"{message}");
- });
- }
Discussion
We can use session in order to share information between different HTTP requests coming from a single browser. The data is stored in a cache (IDistributedCache implementation to be specific) and accessed via HttpContext.Session property.
A cookie is stored in browser to correlated the HTTP requests. The default name of this cookie is .AspNet.Session.
During the configuration of session services we can set various properties,
- HttpOnly - sets whether cookie is accessible through JavaScript. Default is true, which means it can’t be accessed via scripts on the client-side.
- Name - used to override the default cookie name.
- SecurePolicy - determines if session cookie is only transmitted via HTTPS requests.
- IdleTimeout - sets the time for session expiry, each request resets the timeout. Default is 20 mintues.
- public void ConfigureServices(
- IServiceCollection services)
- {
- services.AddDistributedMemoryCache();
- services.AddSession(options =>
- {
- options.Cookie.HttpOnly = true;
- options.Cookie.Name = ".Fiver.Session";
- options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
- options.IdleTimeout = TimeSpan.FromMinutes(10);
- });
- }
Storing Objects
HttpContext.Session (or ISession that it implements) does not provide a built-in way to store complex objects, however, we can serialise objects into JSON strings to achieve this,
- public static class SessionExtensions
- {
- public static void SetObject<T>(this ISession session, string key, T value)
- {
- session.SetString(key, JsonConvert.SerializeObject(value));
- }
-
- public static T GetObject<T>(this ISession session, string key)
- {
- var value = session.GetString(key);
- return value == null ? default(T) :
- JsonConvert.DeserializeObject<T>(value);
- }
- }
Now we can use these extension methods like below,
- public void Configure(
- IApplicationBuilder app,
- IHostingEnvironment env,
- ILoggerFactory loggerFactory)
- {
- app.UseSession();
-
- app.Use(async (context, next) =>
- {
- context.Session.SetObject("CurrentUser",
- new UserInfo { Username = "James", Email = "[email protected]" });
- await next();
- });
-
- app.Run(async (context) =>
- {
- var user = context.Session.GetObject<UserInfo>("CurrentUser");
- await context.Response.WriteAsync($"{user.Username}, {user.Email}");
- });
- }
Accessing via Dependency Injection
To access session using dependency injection you could use IHttpContextAccessor (via constructor), which gives you access to HttpContext.
Source Code
GitHub