ASP.Net MVC 4 SimpleMembership“重新发送确认电子邮件”

时间:2013-03-28 16:28:27

标签: c# .net asp.net-mvc entity-framework asp.net-mvc-4

我为“自动生成的”webpages_Membership表创建了一个模型,以便在用户丢失确认电子邮件以便能够重新发送时,我可以阅读ConfirmationToken。这是我在AccountModels.cs中的代码:

[Table("webpages_Membership")]
public class webpages_Membership
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public Nullable<DateTime> CreateDate { get; set; }
    public string ConfirmationToken { get; set; }
    public Nullable<bool> IsConfirmed { get; set; }
    public Nullable<DateTime> LastPasswordFailureDate { get; set; }
    public int PasswordFailuresSinceLastSuccess { get; set; }
    public string Password { get; set; }
    public Nullable<DateTime> PasswordChangedDate { get; set; }
    public string PasswordSalt { get; set; }
    public string PasswordVerificationToken { get; set; }
    public Nullable<DateTime> PasswordVerificationTokenExpirationDate { get; set; }
}

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<webpages_Membership> webpages_Membership { get; set; }
}

在创建此模型之前,我能够使用以下代码行在App_Start上插入单个用户:

if (Membership.Provider.GetUser("admin", false) == null)
        {
            ((SimpleMembershipProvider)Membership.Provider).CreateUserAndAccount("admin", "bidchuck");
        }

然而,在实现此模型之后,该行现在抛出异常:

[SqlException (0x80131904): Cannot insert explicit value for identity column in table 'webpages_Membership' when IDENTITY_INSERT is set to OFF.]

所以,我怀疑我的模型代码读取此表中的数据与WebSecurity自动生成表的方式有冲突,这是异常的原因。任何人都可以解释如何更改我的模型代码,以便WebSecurity可以自己的方式自动创建表吗?

或者,建议我实施“重新发送确认电子邮件”的其他方式

谢谢!

1 个答案:

答案 0 :(得分:0)

问题在于:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

你明确告诉EF这是一个标识列(即它应该为你生成一个id)。但是,UserId来自ASP.NET成员资格,因此您的表 实际上不会生成id。

注意:删除该行后,您必须进行迁移。

<强>更新

  1. 创建POCO以对表进行建模:

    [Table("webpages_Membership")]
    public class Membership
    {
        public Membership()
        {
            Roles = new List<Role>();
            OAuthMemberships = new List<OAuthMembership>();
        }
    
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int UserId { get; set; }
        public DateTime? CreateDate { get; set; }
        [StringLength(128)]
        public string ConfirmationToken { get; set; }
        public bool? IsConfirmed { get; set; }
        public DateTime? LastPasswordFailureDate { get; set; }
        public int PasswordFailuresSinceLastSuccess { get; set; }
        [Required, StringLength(128)]
        public string Password { get; set; }
        public DateTime? PasswordChangedDate { get; set; }
        [Required, StringLength(128)]
        public string PasswordSalt { get; set; }
        [StringLength(128)]
        public string PasswordVerificationToken { get; set; }
        public DateTime? PasswordVerificationTokenExpirationDate { get; set; }
    
        public ICollection<Role> Roles { get; set; }
    
        [ForeignKey("UserId")]
        public ICollection<OAuthMembership> OAuthMemberships { get; set; }
    }
    

    基本上只是对表格中的字段进行建模。这应该涵盖所有内容,但事情可能已经改变或者可能添加了不同的约束。 [Table("webpages_Membership")]告诉EF要查找哪个表,因为名称或类不完全匹配。

  2. 将您的POCO连接到DbContext子类。您将需要使用与实际映射实体(您迁移的实体,使用更新数据库等)所使用的上下文不同的上下文。数据库初始化策略是在DbContext级别设置的,所以如果你把它添加到你用于其他一切的同一个,它会尝试迁移它,你最终会得到来自EF的讨厌错误。

    public class SimpleMembershipContext : DbContext
    {
        public SimpleMembershipContext()
            : base("name=YourConnectStringName")
        {
            // this tells EF to not worry about migrating or modifying the database
            Database.SetInitializer<SimpleMembershipContext>(null);
        }
    
        public DbSet<Membership> Memberships { get; set; }
    }
    

    将“YourConnectionStringName”替换为项目数据库的连接字符串名称(在web.config中)。如果您将会员资料存储在其他地方,这也可能是一个完全不同的数据库。

  3. 现在,您可以像在任何其他实体中一样在代码中使用它:

    var membershipDb = new SimpleMembershipContext();
    var someMember = membershipDb.Memberships.Find(userId);