无法序列化会话状态;尝试存储会话数据时发生异常

本文关键字:数据 会话 异常 存储 序列化 会话状态 | 更新日期: 2023-09-27 18:16:01

我使用的是ASP。asp.net身份验证和使用cookie中间件进行身份验证和授权。NET MVC应用程序。但我意识到我的cookie在浏览器的cookie存储库中存储的时间太长了。所以,我决定把它存储到一个服务器中。要做到这一点,我在Startup

中使用下面的代码
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        SlidingExpiration = true,
        SessionStore = new AspNetAuthSessionStore()
    });

SessionStore属性需要一种类型的IAuthenticationSessionStore,我发现在这个链接

但我得到下面的错误,而存储cookie数据

无法序列化会话状态。在《永远的美国》和SQLServer模式,ASP。. NET将序列化会话状态对象,因此,不可序列化的对象或MarshalByRef对象是不允许的。同样的限制也适用于类似的序列化是由自定义会话状态存储在' custom '模式下完成的。

我看到在上面的类AspNetAuthSessionStore中实现IAuthenticationSessionStore.StoreAsync()有一些存储cookie的问题

public Task<string> StoreAsync(AuthenticationTicket ticket)
{
    string key = Guid.NewGuid().ToString();
    HttpContext httpContext = HttpContext.Current;
    CheckSessionAvailable(httpContext);
    httpContext.Session[key + ".Ticket"] = ticket;
    return Task.FromResult(key);
}

我认为在httpContext.Session[key + ".Ticket"] = ticket;行中,分配的对象应该是一个可序列化的对象,而AuthenticationTicket类不是。

那么,我该如何解决这个问题呢?

无法序列化会话状态;尝试存储会话数据时发生异常

为了在由staterver或SQL Server处理的会话中存储一些东西,对象必须要么是一个原语(字符串,int等),要么是"可序列化的"。有点令人恼火的是,这意味着只需像Amit在上面的评论中建议的那样向类添加一个Serializable属性。为什么MVC不能简单地序列化一个没有这个属性的类,这有点神秘,但这就是它的方式。

如果你不能添加Serializable属性,因为在你的情况下,你不控制类,简单地说,你不能在会话中存储的东西,如果你想使用StateServer或SQL Server作为你的会话存储。您可以使用in- process,因为它只是将对象存储在内存中,而不需要对其进行序列化。然而,使用StateServer或SQL Server 要好得多,而仅仅因为这一点而切换到较差的进程内支持将是一个错误,我认为。

现在,我不确定为什么要将它存储在会话中,但是传统上,处理这些类型的最好方法是坚持使用原始类型。而不是存储一个完整的对象,存储一个id或类似的,你可以用来再次获取该对象。然后,您不再需要担心序列化,并且在会话中存储的数据要少得多,这总是一件好事。