0

我们最近在我们的 Asp.net 网站中转移到会话状态“SQL Server”。

我可以看到带有SessionItemShortasNULLSessionItemLong列的会话数据databinary format如下所示。

在此处输入图像描述

根据研究,SessionItemLong数据存储在collection of 8-KB pagesandnot in Image数据类型中。

在此处输入图像描述

我尝试转换为图像,但没有成功。

我需要看看SessionItemLong持有什么样的细节。

有什么方法可以反序列化表中SessionItemLong列中的数据ASPStateTempSessions

4

1 回答 1

1

任何在反序列化问题上苦苦挣扎的人:

  1. 创建与表Model映射的实体类。ASPStateTempSessions
  2. 使用以下代码:
public object GetSession(SSOSessionEntity sentity)
{
    object obj = null;
    
    if(sentity.SessionItemLong is null)
    {
        return obj;
    }
    
    System.IO.MemoryStream stream = new System.IO.MemoryStream();
    System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);
    stream.SetLength(0);
    stream.Write(sentity.SessionItemLong, 0, sentity.SessionItemLong.Length);
    stream.Seek(0, System.IO.SeekOrigin.Begin);
    reader.ReadInt32();
    bool bol_flag = reader.ReadBoolean();
    reader.ReadBoolean();
    if(bol_flag)
    {
        SessionStateItemCollection sessionItems = System.Web.SessionState.SessionStateItemCollection.Deserialize(reader);
        foreach(string key in sessionItems.Keys) // All Session in the current sessionid
        {
            obj = sessionItems[key];
            double totalSessionBytes = 0;
            BinaryFormatter b = new BinaryFormatter();
            MemoryStream m;
            var sessionKeyObj = sessionItems[key];
            if(sessionKeyObj != null)
            {
                m = new MemoryStream();
                b.Serialize(m, obj);
                totalSessionBytes += m.Length;
            }
            totalSessionBytes = totalSessionBytes / 1024;
        }
    }
    
    return obj;    
}

SSOSessionEntity只不过是从那里收到的数据select * from dbo.ASPStateTempSessions where sessionid=@sessionid

public SSOSessionEntity GetSessionRow(string connectionString, string sessionId)
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();
        SqlCommand cmd = new SqlCommand("Select * FROM dbo.ASPStateTempSessions WHERE SessionId = @SessionId", con);
        cmd.Parameters.AddWithValue("@SessionId", sessionId);
        SqlDataReader rdr = cmd.ExecuteReader();
        
        DataTable dataTable = new DataTable();

        if (!rdr.HasRows)
        {
            return null;
        }
        
        dataTable.Load(rdr);        
        var row = dataTable.Rows[0];

        return new SSOSessionEntity
        {
            SessionId = (string)row["SessionId"],
            Created = (DateTime)row["Created"],
            Expires = (DateTime)row["Expires"],
            LockDate = (DateTime)row["LockDate"],
            LockDateLocal = (DateTime)row["LockDateLocal"],
            LockCookie = (int)row["LockCookie"],
            Timeout = (int)row["Timeout"],
            Locked = (bool)row["Locked"],
            SessionItemShort = row.IsNull("SessionItemShort") ? null : (byte[])row["SessionItemShort"],
            SessionItemLong = row.IsNull("SessionItemLong") ? null : (byte[])row["SessionItemLong"],
            Flags = (int)row["Flags"],
        };
    }    
}

public class SSOSessionEntity 
{
    public string SessionId { get; set; }
    
    public DateTime Created { get; set; }
    
    public DateTime Expires { get; set; }
    
    public DateTime LockDate { get; set; }
    
    public DateTime LockDateLocal { get; set; }
    
    public int LockCookie { get; set; }
    
    public int Timeout { get; set; }
    
    public bool Locked { get; set; }
    
    public byte[] SessionItemShort { get; set; }
    
    public byte[] SessionItemLong { get; set; }
    
    public int Flags { get; set; }
}

注意:这适用于存储在SessionItemLong列中的数据。
同样也可以用于SessionItemShort列。

于 2020-12-07T16:08:24.250 回答