Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# asp.net会话未存储在sql中_C#_Asp.net Mvc_Session - Fatal编程技术网

C# asp.net会话未存储在sql中

C# asp.net会话未存储在sql中,c#,asp.net-mvc,session,C#,Asp.net Mvc,Session,我使用asp.net mvc 5网站模板项目和个人用户帐户,基于实体框架编写了自己的自定义会话状态提供程序。 当我启动应用程序,注册一个新的网站用户并登录时,数据库表中不会存储诸如UserId之类的会话信息,除非我手动将一些值设置为session变量。在调试了我的自定义会话状态提供程序之后,我可以说它工作得很好,但这不是我想要的 我假设每个网站页面加载都使用唯一的会话id启动新会话或继续当前会话,会话id存储在浏览器cookie中,并通过自定义会话状态提供程序写入数据库。我试图实现这样的应用程序

我使用asp.net mvc 5网站模板项目和个人用户帐户,基于
实体框架
编写了自己的
自定义会话状态提供程序
。 当我启动应用程序,注册一个新的网站用户并登录时,数据库表中不会存储诸如
UserId
之类的会话信息,除非我手动将一些值设置为
session
变量。在调试了我的
自定义会话状态提供程序之后,我可以说它工作得很好,但这不是我想要的

我假设每个网站页面加载都使用唯一的会话id启动新会话或继续当前会话,会话id存储在浏览器cookie中,并通过
自定义会话状态提供程序写入数据库。我试图实现这样的应用程序行为,如何实现这样的应用程序行为

在这个问题上苦苦挣扎了6个月后,我完全明白了

更新

我想跟踪数据库中的所有会话,即使是匿名用户的空会话,但只有在我将一些值设置为
Session
变量时,才会创建新会话数据库记录。我还需要在更改密码时强制用户从所有计算机/浏览器注销。asp.net会话状态机制很复杂,我无法理解

public class WebsiteSessionStateProvider : SessionStateStoreProviderBase
{
    WebsiteDbContext m_DbContext;
    int m_Timeout;

    public WebsiteDbContext DatabaseContext
    {
        get
        {
            return m_DbContext ?? HttpContext.Current.GetOwinContext().GetUserManager<WebsiteDbContext>();
        }
        private set
        {
            m_DbContext = value;
        }
    }

    public override void Initialize(string name, NameValueCollection config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        base.Initialize(name, config);

        var applicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
        var configuration = WebConfigurationManager.OpenWebConfiguration(applicationName);

        var configSection = (SessionStateSection)configuration.GetSection("system.web/sessionState");
        m_Timeout = (int)configSection.Timeout.TotalMinutes;
    }

    public override void Dispose()
    {

    }

    public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
    {
        return GetSessionItem(context, id, false, out locked, out lockAge, out lockId, out actions);
    }

    public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
    {
        return GetSessionItem(context, id, true, out locked, out lockAge, out lockId, out actions);
    }

    private SessionStateStoreData GetSessionItem(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
    {
        locked = false;
        lockAge = new TimeSpan();
        lockId = null;
        actions = 0;

        var SessionItem = DatabaseContext.Sessions.Find(id);

        if (SessionItem == null) return null;

        if (SessionItem.IsLocked)
        {
            locked = true;
            lockAge = DateTime.UtcNow - SessionItem.TimeLocked;
            lockId = SessionItem.LockId;
            return null;
        }

        if (DateTime.UtcNow > SessionItem.TimeExpires)
        {
            DatabaseContext.Entry(SessionItem).State = EntityState.Deleted;
            DatabaseContext.SaveChanges();
            return null;
        }

        if (exclusive)
        {
            SessionItem.LockId += 1;
            SessionItem.IsLocked = true;
            SessionItem.TimeLocked = DateTime.UtcNow;
            DatabaseContext.SaveChanges();
        }

        locked = exclusive;
        lockAge = DateTime.UtcNow - SessionItem.TimeLocked;
        lockId = SessionItem.LockId;

        var data = (SessionItem.Content == null)
            ? CreateNewStoreData(context, m_Timeout)
            : Deserialize(context, SessionItem.Content, m_Timeout);

        data.Items["UserId"] = SessionItem.User.Id;

        return data;
    }

    public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
    {
        var SessionItem = DatabaseContext.Sessions.Find(id);
        if (SessionItem.LockId != (int)lockId) return;

        SessionItem.IsLocked = false;
        SessionItem.TimeExpires = DateTime.UtcNow.AddMinutes(m_Timeout);
        DatabaseContext.SaveChanges();
    }

    public override void SetAndReleaseItemExclusive(HttpContext context,
                                                    string id,
                                                    SessionStateStoreData item,
                                                    object lockId,
                                                    bool newItem)
    {
        var intLockId = lockId == null ? 0 : (int)lockId;
        var userId = (string)item.Items["UserId"];

        var data = ((SessionStateItemCollection)item.Items);
        data.Remove("UserId");

        var Content = Serialize(data);

        if (newItem)
        {
            var session = new Session
            {
                SessionId = id,
                User = DatabaseContext.Users.Find(userId),
                TimeCreated = DateTime.UtcNow,
                TimeExpires = DateTime.UtcNow.AddMinutes(m_Timeout),
                TimeLocked = DateTime.UtcNow,
                IsLocked = false,
                Content = Content,
                LockId = 0,
            };

            DatabaseContext.Sessions.Add(session);
            DatabaseContext.SaveChanges();
            return;
        }

        var state = DatabaseContext.Sessions.Find(id);
        if (state.LockId == (int)lockId)
        {
            state.User = DatabaseContext.Users.Find(userId);
            state.Content = Content;
            state.TimeExpires = DateTime.UtcNow.AddMinutes(m_Timeout);
            state.IsLocked = false;
            DatabaseContext.SaveChanges();
        }
    }

    public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
    {
        var state = DatabaseContext.Sessions.Find(id);
        if (state.LockId != (int)lockId) return;

        DatabaseContext.Entry(state).State = EntityState.Deleted;
        DatabaseContext.SaveChanges();
    }

    public override void ResetItemTimeout(HttpContext context, string id)
    {
        var SessionItem = DatabaseContext.Sessions.Find(id);
        if (SessionItem == null) return;

        SessionItem.TimeExpires = DateTime.UtcNow.AddMinutes(m_Timeout);
        DatabaseContext.SaveChanges();
    }

    public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
    {
        var data = new SessionStateStoreData(new SessionStateItemCollection(),
                                                SessionStateUtility.GetSessionStaticObjects(context),
                                                timeout);

        data.Items["UserId"] = String.Empty;
        return data;
    }

    public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
    {
        var session = new Session
        {
            SessionId = id,
            User = null,
            TimeCreated = DateTime.UtcNow,
            TimeExpires = DateTime.UtcNow.AddMinutes(timeout),
            TimeLocked = DateTime.UtcNow,
            IsLocked = false,
            Content = null,
            LockId = 0,
        };

        DatabaseContext.Sessions.Add(session);
        DatabaseContext.SaveChanges();
    }

    public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) { return false; }
    public override void EndRequest(HttpContext context) { }
    public override void InitializeRequest(HttpContext context) { }

    private byte[] Serialize(SessionStateItemCollection items)
    {
        var ms = new MemoryStream();
        var writer = new BinaryWriter(ms);

        if (items != null) items.Serialize(writer);
        writer.Close();

        return ms.ToArray();
    }

    private SessionStateStoreData Deserialize(HttpContext context, Byte[] serializedItems, int timeout)
    {
        var ms = new MemoryStream(serializedItems);

        var SessionItems = new SessionStateItemCollection();

        if (ms.Length > 0)
        {
            var reader = new BinaryReader(ms);
            SessionItems = SessionStateItemCollection.Deserialize(reader);
        }

        return new SessionStateStoreData(SessionItems, SessionStateUtility.GetSessionStaticObjects(context), timeout);
    }

}
公共类网站SessionStateProvider:SessionStateStoreProviderBase
{
WebsitedContext m_DbContext;
int m_超时;
公共网站上下文数据库上下文
{
得到
{
返回m_DbContext??HttpContext.Current.GetOwinContext().GetUserManager();
}
专用设备
{
m_DbContext=值;
}
}
公共覆盖无效初始化(字符串名称,NameValueCollection配置)
{
如果(config==null)抛出新的ArgumentNullException(nameof(config));
初始化(名称、配置);
var applicationName=System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
var configuration=WebConfigurationManager.OpenWebConfiguration(applicationName);
var configSection=(SessionStateSection)configuration.GetSection(“system.web/sessionState”);
m_Timeout=(int)configSection.Timeout.TotalMinutes;
}
公共覆盖无效处置()
{
}
public override SessionStateStoreData GetItem(HttpContext上下文、字符串id、out bool locked、out TimeSpan lockAge、out object lockId、out SessionStateActions操作)
{
返回GetSessionItem(上下文、id、false、out-locked、out-lockAge、out-lockId、out-actions);
}
public override SessionStateStoreData GetItemExclusive(HttpContext上下文、字符串id、out bool locked、out TimeSpan lockAge、out object lockId、out SessionStateActions操作)
{
返回GetSessionItem(上下文、id、true、out-locked、out-lockAge、out-lockId、out-actions);
}
private SessionStateStoreData GetSessionItem(HttpContext上下文、字符串id、bool独占、out bool锁定、out TimeSpan锁定、out对象锁定id、out SessionStateActions操作)
{
锁定=错误;
锁定=新的时间跨度();
lockId=null;
动作=0;
var SessionItem=DatabaseContext.Sessions.Find(id);
if(SessionItem==null)返回null;
如果(SessionItem.IsLocked)
{
锁定=真;
lockAge=DateTime.UtcNow-SessionItem.TimeLocked;
lockId=SessionItem.lockId;
返回null;
}
如果(DateTime.UtcNow>SessionItem.TimeExpires)
{
DatabaseContext.Entry(SessionItem).State=EntityState.Deleted;
DatabaseContext.SaveChanges();
返回null;
}
如有(不含)
{
SessionItem.LockId+=1;
SessionItem.IsLocked=true;
SessionItem.TimeLocked=DateTime.UtcNow;
DatabaseContext.SaveChanges();
}
锁定=独占;
lockAge=DateTime.UtcNow-SessionItem.TimeLocked;
lockId=SessionItem.lockId;
变量数据=(SessionItem.Content==null)
?CreateNewsStoreData(上下文,m_超时)
:反序列化(上下文、SessionItem.Content、m_超时);
data.Items[“UserId”]=SessionItem.User.Id;
返回数据;
}
public override void ReleaseItemExclusive(HttpContext上下文、字符串id、对象锁定id)
{
var SessionItem=DatabaseContext.Sessions.Find(id);
if(SessionItem.LockId!=(int)LockId)返回;
SessionItem.IsLocked=false;
SessionItem.TimeExpires=DateTime.UtcNow.AddMinutes(m_超时);
DatabaseContext.SaveChanges();
}
public override void SetAndReleaseItemExclusive(HttpContext上下文,
字符串id,
SessionStateStore数据项,
对象lockId,
布尔(新项目)
{
var intLockId=lockId==null?0:(int)lockId;
var userId=(字符串)item.Items[“userId”];
var数据=((SessionStateItemCollection)item.Items);
数据删除(“用户ID”);
变量内容=序列化(数据);
如果(新项目)
{
var会话=新会话
{
SessionId=id,
User=DatabaseContext.Users.Find(userId),
TimeCreated=DateTime.UtcNow,
TimeExpires=DateTime.UtcNow.AddMinutes(m_Timeout),
TimeLocked=DateTime.UtcNow,
IsLocked=false,
内容=内容,
LockId=0,
};
DatabaseContext.Sessions.Add(会话);
DatabaseContext.SaveChanges();
返回;
}
var state=DatabaseContext.Sessions.Find(id);
如果(state.LockId==(int)LockId)
{