2014-04-28 19 views
6

Questa domanda si è evoluta per cui ho aggiornato il titolo.Migrazione di SimpleMembership a Identity 2.0

questo era il titolo originale: Identità 2 UserManager.Find getta "Nome oggetto non valido 'dbo.ApplicationUser'" errore

sto conversione da SimpleMembership a Identità 2. Ho ho fatto funzionare lo script di conversione e refactored i vari file per l'uso di Identity. Posso creare ed eseguire l'app ma quando si tenta di accedere a un errore "Nome oggetto non valido 'dbo.ApplicationUser'" viene generato su var user = UserManager.Find (vM.UserName, vM.Password);

controller

Account:

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

Perché direttore utente tentando di accedere dbo [ApplicationUser] (che non esiste) piuttosto che dbo. [AspNetUsers]?

UPDATE 1: ho declassato a Microsoft.AspNet.Identity.EntityFramework 1.0 e 1.0 e Microsoft.AspNet.Identity.Core io ora ottenere un "nome oggetto non valido 'dbo.IdentityUser'" errore quando UserManager.Find è chiamato.

UPDATE 2:

ho aggiornato torna a Identità 2.0 e solo per vedere cosa sarebbe successo eseguito il backup e cancellato il database e rigenerata con il codice prima (Enable-migrazioni, update-database).

Invece di aggiungere le tabelle predefinite Identità di:
AspNetRoles
AspNetClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers

Essa ha aggiunto queste tabelle:
dbo.ApplicationUser
dbo.IdentityRole
dbo .IdentityUserClaim
dbo.I dentityUserLogin
dbo.IdentityUserRole

Che spiegherebbe perché è alla ricerca di ApplicationUser. Di cosa si tratta la mia configurazione che sta forzando quei nomi al posto dei nomi di identità standard? Probabilmente potrei cambiare il mio script di migrazione con quei nomi, ma poi finirei con nomi di tabelle non standard che porterebbero solo alla confusione in futuro. Come posso configurare le cose per ottenere i nomi delle tabelle Identity di default?

risposta

2

Il problema con i nomi delle tabelle era con l'override di OnModelCreating. Le mie chiamate a .Entity < ...>(). HasKey stava invocando quei nomi di tabelle. Per ulteriori informazioni sull'override vedi la risposta di Olav Nyb0 qui: Asp.net Identity Validation Error.Ho aggiornato l'OnModelCreating a:

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

mio ApplicationUser e la migrazione di script sono stati modellati su Identity 1.0 e avevo bisogno di aggiornarli per Identity 2.0.

ApplicationUser:

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

Ecco lo script di migrazione ho finito con che ho eseguito contro la mia base di dati SimpleMembership. Un po 'fuori dalla domanda iniziale, ma includo qui per sperare di salvare qualcun altro le ore che ho passato a capirlo.

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

non sto usando gli accessi sociali da qui la commentando fuori Inserire nel AspNetUserLogins (si ha bisogno per creare la tabella comunque poiché Identity 2.0 è in attesa di esso).

L'AspNetUsers Tabella Identity 2.0 dispone di questi campi per impostazione predefinita:
[id]
[email]
[email confermata]
[PasswordHash]
[SecurityStamp]
[PhoneNumber]
[PhoneNumberConfirmed]
[TwoFactorEnabled]
[LockoutEndDateUtc]
[LockoutEnabled]
[AccessFailedCount]
[nome utente]

Sto ancora sperimentando, usate il vostro giudizio su ciò che è necessario migrare dalla tabella webpages_Membership. A questo punto posso accedere però.

UPDATE:

Nel mio ApplicationUser avevo ignorato il nome utente da accorciare il campo. NON farlo, causerà un errore di autenticazione. È possibile controllare la lunghezza del campo nello script di migrazione. Ho rimosso l'override nell'OP. Per ulteriori vedere 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; } 
    } 
Problemi correlati