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

时间:2016-11-03 10:12:01

标签: c# asp.net-mvc serialization asp.net-identity

我在ASP.NET MVC应用程序中使用ASP.NET身份并使用cookie中间件进行身份验证和授权。但我意识到我的cookie在浏览器cookie商店中存储的时间非常长。所以,我决定将它存储到StateServer中。为此,我在我的Startup

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

SessionStore属性需要IAuthenticationSessionStore类型,我发现in this link

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

  

无法序列化会话状态。在' StateServer'和   ' SQLServer的'模式,ASP.NET将序列化会话状态对象,   因此,不可序列化的对象或MarshalByRef对象是   不允许。如果类似的序列化,则适用相同的限制   由自定义会话状态存储在' Custom'中完成。模式。

我看到上面的类IAuthenticationSessionStore.StoreAsync()中的实现AspNetAuthSessionStore在存储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 个答案:

答案 0 :(得分:2)

为了在StateServer或SQL Server处理的会话中存储某些内容,该对象必须是一个原语(string,int等)或者是#34; serializable&#34;。有点令人愤怒的是,这意味着仅仅像上面的评论中提到的Amit那样在课堂上添加Serializable属性。为什么MVC不能简单地序列化没有这个属性的类有点神秘,但这就是它的方式。

如果您无法添加Serializable属性,因为在您的情况下,您无法控制该类,只是,您无法将该内容存储在会话中,如果您希望使用StateServer或SQL Server作为会话存储。你可以使用in-proc,因为它只是将对象存储在内存中,而不需要将其序列化。但是,使用StateServer或SQL Server更好很多,并且我认为仅仅因为这样就切换到劣质的in-proc支持是错误的。

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