【问题标题】:Getting "Unable to serialize the session state" exception while trying to store session data尝试存储会话数据时出现“无法序列化会话状态”异常
【发布时间】:2016-11-03 10:12:01
【问题描述】:

我在我的 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 数据时遇到以下错误

无法序列化会话状态。在“状态服务器”和 'SQLServer' 模式,ASP.NET 将序列化会话状态对象, 结果是不可序列化的对象或 MarshalByRef 对象 不允许。如果类似的序列化,同样的限制适用 由自定义会话状态存储在“自定义”模式下完成。

我看到上述类 AspNetAuthSessionStore 中的 implementationIAuthenticationSessionStore.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 类不是。

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

【问题讨论】:

  • 你控制AuthenticationTicket。在其上添加Serializable 属性。
  • @AmitKumarGhosh 我会这样做的。不幸的是它属于Microsoft.Owin.Security 图书馆。

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


【解决方案1】:

为了在由 StateServer 或 SQL Server 处理的会话中存储某些内容,对象必须是基元(字符串、整数等)或“可序列化”。有点令人气愤的是,这意味着仅仅像上面的 cmets 中 Amit 所建议的那样,在类中添加一个 Serializable 属性。为什么 MVC 不能简单地序列化没有这个属性的类有点神秘,但事实就是如此。

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

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

【讨论】:

    猜你喜欢
    • 2012-05-07
    • 2013-09-24
    • 2011-09-01
    • 2021-07-18
    • 1970-01-01
    相关资源
    最近更新 更多