这个问题已经发展了,所以我更新了标题。
这是原标题:Identity 2 UserManager。Find抛出"无效的对象名称'dbo.ApplicationUser'"错误
我正在从SimpleMembership转换为Identity 2。我已经运行了转换脚本,并重构了各种文件以供Identity使用。我可以构建并运行该应用程序,但当尝试登录时,会引发"无效的对象名"dbo.ApplicationUser"错误var user=UserManager。查找(vM.UserName,vM.Password);
账户管理员:
[RequireHttps]
[Authorize]
public class AccountController : Controller
{
private readonly IUserService _userService;
public UserManager<ApplicationUser> UserManager { get; private set; }
public AccountController()
: this(new UserService(), new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDb()))) { }
public AccountController(IUserService userService, UserManager<ApplicationUser> userManager)
{ _userService = userService; UserManager = userManager; }
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login() { return View(); }
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginVm vM)
{
if (ModelState.IsValid)
{
var user = UserManager.Find(vM.UserName, vM.Password);
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName, false);
return RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(vM);
}
应用程序用户:
public class ApplicationUser : IdentityUser
{
[StringLength(15)]
public new string UserName { get; set; }
public int AcId { get; set; }
public int LcId { get; set; }
public string ConfirmationToken { get; set; }
public bool IsConfirmed { get; set; }
public string PasswordResetToken { get; set; }
}
DbContext:
public class MyDb : IdentityDbContext<ApplicationUser> // DbContext
{
public MyDb() : base("MyApplicaiton") { }
// public virtual DbSet<UserProfiles> Users { get; set; }
public virtual DbSet<MyTable> MyTables { get; set; } // properties marked virtual for Mocking override
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
}
为什么用户管理器试图访问dbo。[ApplicationUser](不存在)而不是dbo。[AspNetUsers]?
更新1:我降级到微软。AspNet。身份EntityFramework 1.0和Microsoft。AspNet。身份Core 1.0和我现在在UserManager时收到一个"无效对象名称'dbo.IdentityUser'"错误。将调用Find。
更新2:
我升级回Identity 2.0,只是想看看会发生什么备份和删除数据库,并首先用代码重新生成它(启用迁移,更新数据库)。
而不是添加默认的标识表:
AspNet角色
AspNetClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers
它添加了以下表格:
dbo。应用程序用户
dbo。身份角色
dbo。IdentityUserClaim
dbo。身份用户登录
dbo。身份用户角色
这就解释了它为什么要寻找ApplicationUser。我的配置是如何强制使用这些名称而不是标准标识名称的?我可能会将迁移脚本更改为这些名称,但最终会使用非标准的表名,这只会导致混乱。如何配置以获得默认的标识表名称?
表名的问题在于重写OnModelCreating。我打电话给。实体<…>()。HasKey正在调用那些表名。有关覆盖的更多信息,请参阅Olav Nyb0的答案:Asp.net身份验证错误。我已将OnModelCreating更新为:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
我的ApplicationUser和迁移脚本是在Identity 1.0上建模的,我需要为Identity 2.0更新它们。
应用程序用户:
public class ApplicationUser : IdentityUser
{
public int AcId { get; set; }
public int LcId { get; set; }
}
这是我在SimpleMembership数据库中运行的迁移脚本。有点偏离了最初的问题,但我把它放在这里,希望能为其他人节省我花在解决这个问题上的时间。
/****** Object: Table [dbo].[AspNetRoles] Script Date: 4/29/14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID('dbo.AspNetUserRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUserRoles]
GO
--IF OBJECT_ID('dbo.AspNetUserLogins', 'U') IS NOT NULL
-- DROP TABLE [dbo].[AspNetUserLogins]
--GO
IF OBJECT_ID('dbo.AspNetUserClaims', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUserClaims]
GO
IF OBJECT_ID('dbo.AspNetRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetRoles]
GO
IF OBJECT_ID('dbo.AspNetUsers', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUsers]
GO
CREATE TABLE [dbo].[AspNetUsers] (
[Id] NVARCHAR (128) NOT NULL,
[UserName] NVARCHAR (15) NULL,
[AcId] INT NOT NULL,
[LcId] INT NOT NULL,
[Email] NVARCHAR (256) NULL,
[EmailConfirmed] BIT DEFAULT ((0)) NULL,
[PasswordHash] NVARCHAR (MAX) NULL,
[SecurityStamp] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[PhoneNumberConfirmed] BIT DEFAULT ((0)) NULL,
[TwoFactorEnabled] BIT DEFAULT ((0)) NULL,
[LockoutEndDateUtc] DATETIME NULL,
[Lockoutenabled] BIT DEFAULT ((0)) NULL,
[AccessFailedCount] INT DEFAULT ((0)) NOT NULL,
[Discriminator] NVARCHAR (128) NOT NULL,
[CreateDate] DATETIME NULL,
[ConfirmationToken] NVARCHAR (128) NULL,
[IsConfirmed] BIT DEFAULT ((0)) NULL,
[LastPasswordFailureDate] DATETIME NULL,
[PasswordFailuresSinceLastSuccess] INT DEFAULT ((0)) NULL,
[PasswordChangedDate] DATETIME NULL,
[PasswordVerificationToken] NVARCHAR (128) NULL,
[PasswordVerificationTokenExpirationDate] DATETIME NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE [dbo].[AspNetRoles] (
[Id] NVARCHAR (128) NOT NULL,
[Name] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_dbo.AspNetRoles] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE [dbo].[AspNetUserRoles] (
[UserId] NVARCHAR (128) NOT NULL,
[RoleId] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserRoles] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[AspNetRoles] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_RoleId]
ON [dbo].[AspNetUserRoles]([RoleId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_UserId]
ON [dbo].[AspNetUserRoles]([UserId] ASC);
GO
CREATE TABLE [dbo].[AspNetUserLogins] (
[UserId] NVARCHAR (128) NOT NULL,
[LoginProvider] NVARCHAR (128) NOT NULL,
[ProviderKey] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserLogins] PRIMARY KEY CLUSTERED ([UserId] ASC, [LoginProvider] ASC, [ProviderKey] ASC),
CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_UserId]
ON [dbo].[AspNetUserLogins]([UserId] ASC);
GO
CREATE TABLE [dbo].[AspNetUserClaims] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[ClaimType] NVARCHAR (MAX) NULL,
[ClaimValue] NVARCHAR (MAX) NULL,
[UserId] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserClaims] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_User_Id] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_User_Id]
ON [dbo].[AspNetUserClaims]([UserId] ASC);
GO
INSERT INTO AspNetUsers(Id, UserName, BaId, OfcId, PasswordHash, SecurityStamp, Discriminator,
CreateDate, ConfirmationToken, IsConfirmed, LastPasswordFailureDate, PasswordFailuresSinceLastSuccess,
PasswordChangedDate, PasswordVerificationToken, PasswordVerificationTokenExpirationDate)
SELECT UserProfile.UserId, UserProfile.UserName, UserProfile.BaId, UserProfile.OfcId,
webpages_Membership.Password, webpages_Membership.PasswordSalt, 'User', CreateDate,
ConfirmationToken, IsConfirmed, LastPasswordFailureDate, PasswordFailuresSinceLastSuccess,
PasswordChangedDate, PasswordVerificationToken, PasswordVerificationTokenExpirationDate
FROM UserProfile
LEFT OUTER JOIN webpages_Membership ON UserProfile.UserId = webpages_Membership.UserId
GO
INSERT INTO AspNetRoles(Id, Name)
SELECT RoleId, RoleName
FROM webpages_Roles
GO
INSERT INTO AspNetUserRoles(UserId, RoleId)
SELECT UserId, RoleId
FROM webpages_UsersInRoles
GO
IF OBJECT_ID('dbo.webpages_OAuthMembership', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_OAuthMembership]
GO
IF OBJECT_ID('dbo.webpages_UsersInRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_UsersInRoles]
GO
IF OBJECT_ID('dbo.webpages_Roles', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_Roles]
GO
IF OBJECT_ID('dbo.UserProfile', 'U') IS NOT NULL
DROP TABLE [dbo].[UserProfile]
GO
IF OBJECT_ID('dbo.webpages_Membership', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_Membership]
GO
--INSERT INTO AspNetUserLogins(UserId, LoginProvider, ProviderKey)
--SELECT UserId, Provider, ProviderUserId
--FROM webpages_OAuthMembership
--GO
我没有使用社交登录,因此Insert到AspNetUserLogins中的注释被删除了(尽管您确实需要创建表,因为Identity 2.0正在期待它)。
Identity 2.0 AspNetUsers表默认具有以下字段:
[Id]
[电子邮件]
[电子邮件已确认]
[PasswordHash]
[SecurityStamp]
[电话号码]
[PhoneNumberConfirmed]
[TwoFactorEnabled]
[锁定结束日期Utc]
[锁定已启用]
[AccessFailedCount]
[用户名]
我仍在尝试,请根据您的最佳判断从webpages_Membership表中迁移什么。现在我可以登录了。
更新:
在ApplicationUser中,我覆盖了UserName以缩短字段。不要这样做,这将导致身份验证错误。您可以控制迁移脚本中的字段长度。我已经删除了OP中的覆盖。有关更多信息,请参阅用户。IsInRole失败。
应用程序用户:
public class ApplicationUser : IdentityUser
{
// [StringLength(15)] // do not override UserName, will cause authentication error.
// public new string UserName { get; set; }
public int AcId { get; set; }
public int LcId { get; set; }
// public string ConfirmationToken { get; set; } // Depends on your app if you need to migrate these fields
// public bool IsConfirmed { get; set; }
// public string PasswordResetToken { get; set; }
}