What's the problem about?
We want to store a DateTime
in Session
, but ASP.NET Core has a direct support only for Int32
and String
type of data; there is no built-in method that allows us to save a DateTime
type.
What's the solution?
The technique is to serialize a DateTime
instance to a json string, and store that string in the session instead. And, deserialize it for retrieval.
The following utility extension methods on ISession are recommended by the ASP.NET Core team.
using Microsoft.AspNetCore.Http; using System.Text.Json; // we wrote it in a folder called // "Utilities" directly in the root // of the project directory namespace MySession.Utilities { public static class SessionExtensions { // extension method on ISession // how to use: HttpContext.Session.Set<T>(key, value) public static void Set<T>(this ISession session, string key, T value) { session.SetString(key, JsonSerializer.Serialize(value)); } // extension method on ISession // how to use: HttpContext.Session.Get<T>(key) public static T Get<T>(this ISession session, string key) { var value = session.GetString(key); return value == null ? default : JsonSerializer.Deserialize<T>(value); } } }
Video Explanation with a Working Example
Please watch the following youtube video:
Objective of this Walkthrough
There is only one razor page in this project. The page is called Index.
When a user starts his session, the system time is saved in a session variable. On subsequent requests/refreshes of the page, this start time is read from the session and shown to him as the start time of his browsing session.
Step 1 of 4: Configure the use of Session
Configure the use of session as explained in the tutorial (C# ASP.NET Core) How to use Session for State Management
Step 2 of 4: Add the Session Extensions
Create any folder, say, Utility and paste the above utility class there, so that we have the Set<T>
and Get<T>
extension methods.
Step 3 of 4: Complete the Index.cshtml.cs file
Complete the backing class as shown below.
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.RazorPages; using MySession.Utilities; using System; using System.ComponentModel.DataAnnotations; namespace MySession.Pages { public class IndexModel : PageModel { // a string for the session key // this will prevent bugs due to // bad typing internal const string SESS_START = "SKEY_STIME"; // start time of this session // apply format 4:35:02 PM 27-Aug-2021 [DisplayFormat(DataFormatString = @"{0:h\:mm\:ss tt dd-MMM-yyyy}")] public DateTime StartTime { get; private set; } // when the index page is requested public void OnGet() { // read the stored datetime StartTime = HttpContext.Session.Get<DateTime>(SESS_START); // if empty, i.e, default (i.e., DateTime.UnspecifiedKind) if (StartTime == default) { StartTime = DateTime.Now; // store the current time HttpContext.Session.Set<DateTime>(SESS_START, StartTime); } } } }
Step 4 of 4: Complete the Index.cshtml Razor file
Complete the razor mark-up file as shown below.
@page @model MySession.Pages.IndexModel @if (Model.StartTime != default) { <div> This session started: @Html.DisplayFor(x => Model.StartTime) </div> }
This Blog Post/Article "(C# ASP.NET Core) Serializing DateTime into Session" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.