首页 文章

尝试存储会话数据时出现“无法序列化会话状态”异常

提问于
浏览
0

我在 ASP.NET MVC 应用程序中使用 ASP.NET 身份并使用 cookie middle-ware 进行身份验证和授权。但我意识到我的 cookie 在浏览器 cookie 商店中存储的时间非常长。所以,我决定将它存储到 StateServer 中。要做到这一点,我在我的Startup类中使用波纹管代码

app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        SlidingExpiration = true,
        SessionStore = new AspNetAuthSessionStore()
    });

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

但是我在存储 cookie 数据时遇到以下错误

无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许使用 non-serializable 对象或 MarshalByRef 对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则适用相同的限制。

我看到上面的类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;行中,分配的对象应该是 Serializable 对象而类AuthenticationTicket不是。

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

1 回答

  • 2

    为了在 StateServer 或 SQL Server 处理的会话中存储某些东西,该对象必须是一个原语(string,int,etc.)或者是“可序列化的”。有点令人恼火的是,这意味着只是像 Amit 所建议的那样在类中添加Serializable属性在上面的评论中。为什么 MVC 不能简单地序列化没有这个属性的类有点神秘,但这就是它的方式。

    如果你不能添加Serializable属性,因为在你的情况下,你不控制类,只是,如果你想使用 StateServer 或 SQL Server 作为你的会话,你不能将那个东西存储在会话中商店。您可以使用 in-proc,因为它只是将对象存储在内存中,而不需要将其序列化。但是,使用 StateServer 或 SQL Server 要好得多,而且我认为,仅仅因为这样就切换到劣质的 in-proc 支持是一个错误。

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

相关问题