Identity 2.0添加额外的电子邮件列

时间:2015-07-09 16:15:01

标签: asp.net-mvc asp.net-mvc-5 asp.net-identity-2

当我尝试登录我的开发网站时,出现了一个奇怪的错误:

  

列名称无效' Email1'。

我为许多不同的ASP.NET Identity 2.0类创建了派生类,即:

public class MyUser : IdentityUser<int, MyLogin, MyUserRole, MyClaim>//, IUser<int>
{
    #region properties

    public string ActivationToken { get; set; }

    public string PasswordAnswer { get; set; }

    public string PasswordQuestion { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string TaxID { get; set; }

    public bool IsActive { get; set; }

    public bool IsApproved { get; set; }

    #endregion

    #region methods

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<MyUser, int> userManager)
    {
        var userIdentity = await userManager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    #endregion
}

违规代码是在AccountController的Login方法中调用UserManager.FindAsync():

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindAsync(model.Email, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }
            ModelState.AddModelError("", "Invalid username or password.");
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

我已经设计了我的用户表格:

CREATE TABLE [dbo].[User]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Password] [nvarchar](50) NOT NULL,
    [FirstName] [nvarchar](50) NULL,
    [LastName] [nvarchar](50) NULL,
    [Email] [nvarchar](50) NOT NULL,
    [TaxID] [nvarchar](50) NULL,
    [PaymentMethodID] [int] NULL,
    [IsActive] [bit] NOT NULL DEFAULT 1,
    [IsApproved] [bit] NOT NULL,
    [IsLocked] [bit] NOT NULL,
    [CreationDate] [datetime] NULL,
    [ApprovalDate] [datetime] NULL DEFAULT NULL,
    [LastLoginDate] [datetime] NULL,
    [PasswordQuestion] [nvarchar](max) NULL,
    [PasswordAnswer] [nvarchar](max) NULL,
    [ActivationToken] [nvarchar](200) NULL,
    [EmailConfirmed] [bit] NOT NULL,
    [SecurityStamp] [nvarchar](max) NULL,
    [PhoneNumber] [nvarchar](50) NULL,
    [PhoneNumberConfirmed] [bit] NOT NULL,
    [TwoFactorEnabled] [bit] NOT NULL,
    [LockoutEndDateUtc] [datetime2](7) NULL,
    [LockoutEnabled] [bit] NOT NULL,
    [AccessFailedCount] [int] NOT NULL,
    CONSTRAINT [User_PK] PRIMARY KEY NONCLUSTERED ([ID]),
    CONSTRAINT [Email_UK] UNIQUE NONCLUSTERED([Email])
)

我在MyDbContext的OnModelCreating方法中将MyUser类绑定到该表:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // Map Entities to their tables.
            modelBuilder.Entity<MyUser>().ToTable("User");
            modelBuilder.Entity<MyRole>().ToTable("Role");
            modelBuilder.Entity<MyClaim>().ToTable("UserClaim");
            modelBuilder.Entity<MyLogin>().ToTable("UserLogin");
            modelBuilder.Entity<MyUserRole>().ToTable("UserRole");
            // Set AutoIncrement-Properties
            modelBuilder.Entity<MyUser>().Property(r => r.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<MyClaim>().Property(r => r.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<MyRole>().Property(r => r.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            // Override some column mappings that do not match our default
            modelBuilder.Entity<MyUser>().Property(r => r.UserName).HasColumnName("Email");
            modelBuilder.Entity<MyUser>().Property(r => r.PasswordHash).HasColumnName("Password");
        }

Identity 2.0正在创建另一个不应该的电子邮件列。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

默认架构中已经有一个名为Email的列。

正如@ enki.dev在他删除的答案中建议的那样,如果你看一下IdentityUser的定义,你已经定义了那些属性。

你在这里做了一件非常危险的事情:

modelBuilder.Entity<MyUser>().Property(r => r.UserName).HasColumnName("Email");
modelBuilder.Entity<MyUser>().Property(r => r.PasswordHash).HasColumnName("Password");

因为你正试图强迫一列进入另一列。电子邮件已在此框架中广泛用于密码检索等。

您可以尝试重命名

modelBuilder.Entity<MyUser>().Property(r => r.Email).HasColumnName("Blah");

所以你不会有副本;但是我想你在路上会遇到很多其他问题。

为什么不将电子邮件存储在UserName属性中?

另一个建议;让框架使用迁移为您创建表格总是更好,这样您就可以随时了解正在发生的事情。

从Visual Studio中选择菜单

  • TOOLS - NuGet Packager Manager - 软件包管理器控制台

在组合中选择您的项目:默认项目。

运行Enable-Migrations

它应该创建一个名为Migrations的文件夹,其中包含一个名为Configuration.cs的文件。

构造函数应如下所示:

public Configuration()
{
    AutomaticMigrationsEnabled = false;
}

将值AutomaticMigrationsEnabled更改为true

返回Package Manager Console并运行

Update-Database

Update-Database -Force

为您的表重新创建整个架构。

在那里有一个受保护的方法,您可以在那里看到您的数据:

protected override void Seed(ASPNETIdentity2.Models.MyContext context)
{
    //  This method will be called after migrating to the latest version.

    //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
    //  to avoid creating duplicate seed data. E.g.
    //
    //    context.People.AddOrUpdate(
    //      p => p.FullName,
    //      new Person { FullName = "Andrew Peters" },
    //      new Person { FullName = "Brice Lambson" },
    //      new Person { FullName = "Rowan Miller" }
    //    );
    //
}