Переход от 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, и теперь я получаю сообщение об ошибке «Недопустимое имя объекта 'dbo.IdentityUser'», когда UserManager.Find называется.

ОБНОВЛЕНИЕ 2:

Я обновился до Identity 2.0 и просто чтобы посмотреть, что произойдет, сделал резервную копию и удалил базу данных, а затем регенерировал ее с помощью кода (enable-migrations, update-database).

Вместо добавления таблиц идентификации по умолчанию:
AspNetRoles
AspNetClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers

Он добавил следующие таблицы:
dbo.ApplicationUser
dbo.IdentityRole
dbo.IdentityUserClaim
dbo.IdentityUserLogin
dbo.IdentityUserRole

Это объясняет, почему он ищет ApplicationUser. Что в моей конфигурации заставляет использовать эти имена вместо стандартных имен удостоверений? Я, вероятно, мог бы изменить свой сценарий миграции на эти имена, но тогда я бы получил нестандартные имена таблиц, которые в дальнейшем только привели бы к путанице. Как мне настроить вещи, чтобы получить имена таблиц идентификаторов по умолчанию?


person Joe    schedule 28.04.2014    source источник


Ответы (1)


Проблема с именами таблиц была связана с переопределением OnModelCreating. Мои вызовы .Entity ‹...> (). HasKey вызывали эти имена таблиц. Дополнительную информацию о переопределении см. В ответе Олава Нюб0 здесь: Ошибка проверки подлинности Asp.net. Я обновил 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', 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]
[Электронная почта]
[EmailConfirmed]
[PasswordHash]
[SecurityStamp]
[PhoneNumber]
[PhoneNumberConfirmed]
[TwoFactorEnabled]
[LockoutEndDateUtc]
[LockoutEnabled]
[AccessFailedCount]
[UserName]

Я все еще экспериментирую, постарайтесь решить, что вам нужно перенести из таблицы webpages_Membership. На данный момент я могу войти в систему.

ОБНОВЛЕНИЕ:

В моем ApplicationUser я переопределил UserName, чтобы сократить поле. НЕ делайте этого, это вызовет ошибку аутентификации. Вы можете контролировать длину поля в скрипте миграции. Я удалил переопределение в OP. Подробнее см. Ошибка User.IsInRole.

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; }
  }
person Joe    schedule 29.04.2014