Identity 2.0 添加额外的电子邮件列
Identity 2.0 Adding extra Email column
当我尝试登录我的开发站点时,出现一个奇怪的错误:
Invalid column name 'Email1'.
我已经为许多不同的 ASP.NET Identity 2.0 classes 派生了 classes,即:
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 的登录方法中对 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);
}
我这样设计我的用户 table:
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 class 绑定到 table:
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 正在创建另一个不应创建的电子邮件列。有什么想法吗?
默认架构中已经有名称为 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 选择菜单
- 工具 - NuGet Packager Manager - 包管理器控制台
select 您在组合中的项目:默认项目。
运行 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" }
// );
//
}
当我尝试登录我的开发站点时,出现一个奇怪的错误:
Invalid column name 'Email1'.
我已经为许多不同的 ASP.NET Identity 2.0 classes 派生了 classes,即:
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 的登录方法中对 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);
}
我这样设计我的用户 table:
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 class 绑定到 table:
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 正在创建另一个不应创建的电子邮件列。有什么想法吗?
默认架构中已经有名称为 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 选择菜单
- 工具 - NuGet Packager Manager - 包管理器控制台
select 您在组合中的项目:默认项目。
运行 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" }
// );
//
}