Session.IsNewSession 在 ASP.NET 核心

Session.IsNewSession in ASP.NET Core

我正在将 ASP.NET MVC 应用程序迁移到 ASP.NET Core 3.1。

我有一个代码可以检查控制器中的会话是否超时,如下所示:

if (Session.IsNewSession) {

如何在 ASP.NET Core 中检查它?

谢谢

ISession 的默认实现是 DistributedSession。尽管它的构造函数接受名为 isNewSessionKey 的参数,但它不会为 IsNewSession 公开任何 属性。所以你可以使用 reflection 来获取 _isNewSessionKey 的私有字段来检查它。但是这种方式不是很标准,将来可能会更改名称而不会通知您任何设计时错误。

您有几个要点可以在此处拦截并获取信息。第一点是创建自定义 ISessionStore(默认为 DistributedSessionStore)以拦截对 ISessionStore.Create 的调用,从而可以访问 isNewSessionKey。您可以将该值捕获到请求功能中,就像框架在创建会话后如何设置 ISessionFeature 一样。这是代码:

//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;
     }
}

要在您的代码中使用它:

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

拦截和获取信息的另一点是自定义 ISessionStoreISession。这意味着您创建 DistributedSession 的子 class 并公开 IsNewSession 的 属性。这可能需要更多代码,但它看起来更像是获取信息的旧方法(直接从 Session 而不是通过 HttpContext 上的扩展方法)。