asp.net-identity entity-framework-6.1

asp.net identity - Migración de SimpleMembership a Identity 2.0



asp.net-identity entity-framework-6.1 (1)

Esta pregunta ha evolucionado, así que actualicé el título.

Este fue el título original: Identity 2 UserManager.Find arroja el error "Nombre de objeto no válido ''dbo.ApplicationUser''"

Estoy convirtiendo de SimpleMembership a Identity 2. He ejecutado el script de conversión y refactorizado los diversos archivos para el uso de Identity. Puedo compilar y ejecutar la aplicación, pero cuando intento iniciar sesión aparece un error "Nombre de objeto no válido ''dbo.ApplicationUser''" en var user = UserManager.Find (vM.UserName, vM.Password);

Controlador de cuenta:

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

¿Por qué el administrador de usuarios intenta acceder a dbo. [ApplicationUser] (que no existe) en lugar de dbo. [AspNetUsers]?

ACTUALIZACIÓN 1: Me degradaron a Microsoft.AspNet.Identity.EntityFramework 1.0 y Microsoft.AspNet.Identity.Core 1.0 y ahora recibo un error "Nombre de objeto no válido ''dbo.IdentityUser''" cuando se llama a UserManager.Find.

ACTUALIZACIÓN 2:

Me actualicé nuevamente a Identity 2.0 y solo para ver qué sucedería, hice una copia de seguridad y borré la base de datos y la regeneré con el código primero (enable-migrations, update-database).

En lugar de agregar las tablas de identidad predeterminadas de:
AspNetRoles
AspNetClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers

Agregó estas tablas:
dbo.ApplicationUser
dbo.IdentityRole
dbo.IdentityUserClaim
dbo.IdentityUserLogin
dbo.IdentityUserRole

Lo que explicaría por qué está buscando ApplicationUser. ¿De qué se trata mi configuración que está forzando esos nombres en lugar de los nombres de identidad estándar? Probablemente podría cambiar mi script de migración a esos nombres, pero luego terminaría con nombres de tabla no estándar que solo conducirían a confusión en el futuro. ¿Cómo configuro las cosas para obtener los nombres predeterminados de la tabla de identidad?


El problema con los nombres de tabla era con la anulación de OnModelCreating. Mis llamadas a .Entity <...> (). HasKey invocaba esos nombres de tabla. Para obtener más información sobre la anulación, vea la respuesta de Olav Nyb0 aquí: Error de validación de identidad de Asp.net . Actualicé OnModelCreating a:

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

My ApplicationUser y script de migración fueron modelados en Identity 1.0 y necesitaba actualizarlos para Identity 2.0.

ApplicationUser:

public class ApplicationUser : IdentityUser { public int AcId { get; set; } public int LcId { get; set; } }

Aquí está el script de migración con el que terminé y que corro contra mi base de datos SimpleMembership. Un poco fuera de la pregunta original, pero la incluyo aquí para salvar a alguien más las horas que dediqué a descifrarlo.

/****** 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

No utilizo los inicios de sesión sociales, por lo tanto, el comentario de Insertar en AspNetUserLogins (aunque es necesario crear la tabla, ya que Identity 2.0 lo espera).

La tabla Identity 2.0 AspNetUsers tiene estos campos por defecto:
[Carné de identidad]
[Email]
[Correo electrónico confirmado]
[PasswordHash]
[SecurityStamp]
[Número de teléfono]
[PhoneNumberConfirmed]
[TwoFactorEnabled]
[LockoutEndDateUtc]
[LockoutEnabled]
[AccessFailedCount]
[Nombre de usuario]

Todavía estoy experimentando, use su mejor criterio en cuanto a lo que necesita para migrar desde la tabla de páginas web_Membresía. En este punto, puedo iniciar sesión sin embargo.

ACTUALIZAR:

En mi ApplicationUser, he anulado el UserName para acortar el campo. NO haga esto, causará un error de autenticación. Puede controlar la longitud del campo en el script de migración. Eliminé la anulación en el OP. Para obtener más información, vea el error de 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; } }