Rodrigo Kiguti
Rodrigo Kiguti

Reputation: 542

Session.IsNewSession in ASP.NET Core

I am migrating an ASP.NET MVC application to ASP.NET Core 3.1.

And I have a code to check if the session was timed out in my controller, like this:

if (Session.IsNewSession) {

How can I check it in ASP.NET Core?

Thanks

Upvotes: 1

Views: 1340

Answers (1)

King King
King King

Reputation: 63377

The default implementation of ISession is DistributedSession. This does not expose any property for IsNewSession although its constructor accepts a parameter named isNewSessionKey. So you can use reflection to get that private field of _isNewSessionKey to check it. But that way is not very standard, the name may be changed in future without notifying you any design-time error.

You have several points to intercept and get the info here. The first point is to create a custom ISessionStore (default by DistributedSessionStore) to intercept the call to ISessionStore.Create which gives access to isNewSessionKey. You can capture that value into a request feature just like how the framework set the ISessionFeature after creating the session. Here's the code:

//create the feature interface & class
public interface ISessionExFeature {
    bool IsNewSession { get; }
}
public class SessionExFeature : ISessionExFeature {
    public SessionExFeature(bool isNewSession){
         IsNewSession = isNewSession;
    }
    public bool IsNewSession { get; }
}

//the custom ISessionStore
public class CustomDistributedSessionStore : DistributedSessionStore, ISessionStore
{        
    readonly IHttpContextAccessor _httpContextAccessor;
    public CustomDistributedSessionStore(IDistributedCache cache, 
        ILoggerFactory loggerFactory,            
        IHttpContextAccessor httpContextAccessor) : base(cache, loggerFactory)
    {            
        _httpContextAccessor = httpContextAccessor;
    }

    ISession ISessionStore.Create(string sessionKey, TimeSpan idleTimeout, TimeSpan ioTimeout, Func<bool> tryEstablishSession, bool isNewSessionKey)
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if(httpContext != null)
        {
            var sessionExFeature = new SessionExFeature(isNewSessionKey);             
            httpContext.Features.Set<ISessionExFeature>(sessionExFeature);
        }
        return Create(sessionKey, idleTimeout, ioTimeout, tryEstablishSession, isNewSessionKey);
    }
}

//register the custom ISessionStore inside Startup.ConfigureServices
services.Replace(new ServiceDescriptor(typeof(ISessionStore), typeof(CustomDistributedSessionStore), ServiceLifetime.Transient));            

//an extension method to help get the ISessionExFeature conveniently
public static class SessionExFeatureHttpContextExtensions {
     public static bool HasNewSession(this HttpContext context){
         return context.Features.Get<ISessionExFeature>()?.IsNewSession ?? false;
     }
}

To use it in your code:

if (HttpContext.HasNewSession()) {
    //...
}

Another point to intercept and get the info is customize both the ISessionStore and ISession. Which means you create a sub class of DistributedSession and expose the property for IsNewSession. That may require more code but it looks more like the old way of getting the info (directly from the Session not kind of via an extension method on HttpContext).

Upvotes: 1

Related Questions