微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-identity – 将SimpleMembership迁移到Identity 2.0

这个问题已经发展,所以我更新了标题.

这是原始标题
Identity 2 UserManager.Find抛出“无效的对象名称’dbo.ApplicationUser’”错误

我正在从SimpleMembership转换为Identity 2.我已经运行了转换脚本并重构了各种文件以供Identity使用.我可以构建并运行应用程序但是当尝试登录“无效对象名称’dbo.ApplicationUser’”时会抛出错误
var user = UserManager.Find(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);
    }

ApplicationUser:

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:
我降级到Microsoft.AspNet.Identity.EntityFramework 1.0和Microsoft.AspNet.Identity.Core 1.0,我现在在调用UserManager.Find时出现“无效对象名’dbo.IdentityUser’”错误.

更新2:

升级回Identity 2.0,只是为了查看备份和删除数据库会发生什么,并首先使用代码重新生成它(enable-migrations,update-database).

而不是添加认的身份表:
AspNetRoles
AspNetClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers

添加了这些表格:
dbo.ApplicationUser
dbo.IdentityRole
dbo.IdentityUserClaim
dbo.IdentityUserLogin
dbo.IdentityUserRole

这可以解释为什么它正在寻找ApplicationUser.我的配置是什么强制这些名称而不是标准的身份名称?我可能可以将我的迁移脚本更改为这些名称,但最后我会得到非标准的表名,这只会导致混乱.如何配置以获取认的标识表名称

解决方法

表名的问题在于覆盖OnModelCreating.我调用.Entity< ...>().HasKey正在调用这些表名.有关覆盖的更多信息,请参阅Olav Nyb0的答案: Asp.net Identity Validation Error.我已将OnModelCreating更新为:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);
  modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

我的ApplicationUser和迁移脚本是在Identity 1.0上建模的,我需要为Identity 2.0更新它们.

ApplicationUser:

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',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

我没有使用社交登录因此注释掉插入AspNetUserLogins(你确实需要创建表,因为Identity 2.0期待它).

Identity 2.0 AspNetUsers表认包含以下字段:
[ID]
[电子邮件]
[EmailConfirmed]
[PasswordHash]
[SecurityStamp]
[电话号码]
[PhoneNumberConfirmed]
[TwoFactorEnabled]
[LockoutEndDateUtc]
[LockoutEnabled]
[AccessFailedCount]
[用户名]

我还在尝试,根据你在webpages_Membership表中迁移的内容,使用你最好的判断.此时我可以登录了.

更新:

在我的ApplicationUser中,我重写了UserName以缩短字段.不要这样做,它会导致身份验证错误.您可以在迁移脚本中控制字段长度.我删除了OP中的覆盖.欲了解更多,请参阅User.IsInRole failing.

ApplicationUser:

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; }
  }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐