'Microsoft.AspNet.Identity.EntityFramework.IdentityUser' 未标记为可序列化

'Microsoft.AspNet.Identity.EntityFramework.IdentityUser' is not marked as serializable

我正在一个系统中实现 ASP.NET 身份,该系统使用 Entity Framework 的用户模型进行身份验证,并在 WebApp 中由 Session 控制(是的,它是 Web 表单中的遗留系统),我们已实施,将 User 模型替换为 ApplicationUser 身份,一切正常。

问题是,有一个通知系统,它基本上是 NotificationUser 模型之间的多对多关系, 这些通知与系统的其余部分一起保存在 SQL 服务器中,但也保存在 Cache Redis 中以加快读取速度,并且需要序列化以便写入。我们删除了 User 模型,然后在 Notification 模型中添加了 ApplicationUserICollection,反之亦然 - 使两者之间存在关联。

但是 ApplicationUser 继承自 IdentityUser,甚至添加注释 [Serializable] 我得到异常:

Type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUser' the assembly 'Microsoft.AspNet.Identity.EntityFramework, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35' is not marked as serializable

我的问题是,有没有办法序列化这个?或者我将不得不创建另一个用户模型只与通知模型相关?

ApplicationUser型号

[Serializable]
public class ApplicationUser : IdentityUser
{
    public ApplicationUser()
    {
        this.Notificacoes = new List<Notificacao>();
    }

    public ClaimsIdentity GenerateUserIdentity(IdentityConfig.ApplicationUserManager manager)
    {
        var userIdentity = manager.CreateIdentity(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }

    public Task<ClaimsIdentity> GenerateUserIdentityAsync(IdentityConfig.ApplicationUserManager manager)
    {
        return Task.FromResult(GenerateUserIdentity(manager));
    }
    public bool ReceiveNotifications { get; set; }
    public int Permission { get; set; }
    public virtual ICollection<Notificacao> Notificacoes { get; set; }
}

Notification 型号

[Serializable]
public partial class Notificacao
{
    public Notificacao()
    {
        this.Usuarios = new List<ApplicationUser>();
    }

    public int Codigo { get; set; }
    public string Mensagem { get; set; }
    public DateTime DataHoraNotificacao { get; set; }
    public int Tipo { get; set; }
    public virtual ICollection<ApplicationUser> Usuarios { get; set; }

}

用于将对象序列化到 Redis 的 Serialize 方法(抛出异常)

static byte[] Serialize(object o)
{
    if (o == null)
    {
        return null;
    }

    BinaryFormatter binaryFormatter = new BinaryFormatter();
    using (MemoryStream memoryStream = new MemoryStream())
    {
        binaryFormatter.Serialize(memoryStream, o);
        byte[] objectDataAsStream = memoryStream.ToArray();
        return objectDataAsStream;
    }
}

由于您无法控制包含 IdentityUser class 的程序集,因此无法完成此操作。另一种解决方案是在缓存之前将您的对象映射到 Dto(数据传输对象),而在获取时则相反。

关于该主题的其他主题(与 WCF 相关但仍涉及序列化 IdentityUser):

asp-net-mvc-5-identityuser-in-wcf

您不想将 IdentityUser 或其任何子 class 序列化到数据库。期间.

如果您需要维护数据库中的关系,请创建一个 POCO(普通旧 CLR 对象 - 简单来说,一个自定义 class)。

此外,如果您需要在用户 class 中携带 IdentityUser,请使用 composition 而不是 继承。这意味着,不要从 IdentityUser 继承,而是在您的 class 中创建它的 属性。并将 属性 标记为 NonSerializable.