it-swarm.com.de

ASP.NET-Identität mit EF Database First MVC5

Ist es möglich, die neue Asp.net-Identität mit Database First und EDMX zu verwenden? Oder erst mit Code?

Folgendes habe ich getan:

1) Ich habe ein neues MVC5-Projekt erstellt und mit der neuen Identität die neuen Benutzer- und Rollentabellen in meiner Datenbank erstellt.

2) Ich habe dann meine Database First EDMX-Datei geöffnet und in die neue Identity Users-Tabelle gezogen, da ich andere Tabellen habe, die sich darauf beziehen.

3) Beim Speichern des EDMX erstellt der Database First POCO-Generator automatisch eine Benutzerklasse. UserManager und RoleManager erwarten jedoch, dass eine Benutzerklasse vom neuen Identitätsnamespace (Microsoft.AspNet.Identity.IUser) erbt, sodass die Verwendung der POCO-Benutzerklasse nicht funktioniert.

Ich vermute, eine mögliche Lösung besteht darin, meine POCO-Generierungsklassen so zu bearbeiten, dass meine Benutzerklasse von IUser erbt.

Oder ist ASP.NET Identity nur mit Code First Design kompatibel?

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

Update: Nach dem Vorschlag von Anders Abel habe ich Folgendes getan. Es funktioniert, aber ich frage mich, ob es eine elegantere Lösung gibt.

1) Ich habe meine Entitätsbenutzerklasse erweitert, indem ich eine Teilklasse im selben Namespace wie meine automatisch generierten Entitäten erstellt habe.

namespace MVC5.DBFirst.Entity
{
    public partial class AspNetUser : IdentityUser
    {
    }
}

2) Ich habe meinen DataContext so geändert, dass er von IdentityDBContext anstelle von DBContext erbt. Beachten Sie, dass Sie jedes Mal, wenn Sie Ihr EDMX aktualisieren und die DBContext- und Entity-Klassen neu generieren, dies auf diesen Wert zurücksetzen müssen.

 public partial class MVC5Test_DBEntities : IdentityDbContext<AspNetUser>  //DbContext

3) In Ihrer automatisch generierten Benutzerentitätsklasse müssen Sie das Überschreibungsschlüsselwort zu den folgenden 4 Feldern hinzufügen oder diese Felder auskommentieren, da sie von IdentityUser geerbt werden (Schritt 1). Beachten Sie, dass Sie jedes Mal, wenn Sie Ihr EDMX aktualisieren und die DBContext- und Entity-Klassen neu generieren, dies auf diesen Wert zurücksetzen müssen.

    override public string Id { get; set; }
    override public string UserName { get; set; }
    override public string PasswordHash { get; set; }
    override public string SecurityStamp { get; set; }
87
Patrick Tran

Es sollte möglich sein, das Identitätssystem mit POCO und Database First zu verwenden, aber Sie müssen einige Änderungen vornehmen:

  1. Aktualisieren Sie die .tt-Datei für die POCO-Generierung, um die Entitätsklassen partial zu erstellen. Auf diese Weise können Sie zusätzliche Implementierungen in einer separaten Datei bereitstellen.
  2. Nehmen Sie eine teilweise Implementierung der Klasse User in einer anderen Datei vor

partial User : IUser
{
}

Dadurch wird die Klasse User die richtige Schnittstelle implementieren, ohne die tatsächlich generierten Dateien zu berühren (das Bearbeiten der generierten Dateien ist immer eine schlechte Idee).

16
Anders Abel

Meine Schritte sind sehr ähnlich, aber ich wollte teilen.

1) Erstellen Sie ein neues MVC5-Projekt

2) Erstellen Sie eine neue Model.edmx. Auch wenn es eine neue Datenbank ist und keine Tabellen hat.

3) Bearbeiten Sie die Datei web.config und ersetzen Sie diese generierte Verbindungszeichenfolge:

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-SSFInventory-20140521115734.mdf;Initial Catalog=aspnet-SSFInventory-20140521115734;Integrated Security=True" providerName="System.Data.SqlClient" />

mit diesem verbindungsstring:

<add name="DefaultConnection" connectionString="Data Source=.\SQLExpress;database=SSFInventory;integrated security=true;" providerName="System.Data.SqlClient" />

Erstellen Sie anschließend die Anwendung, und führen Sie sie aus. Registrieren Sie einen Benutzer und dann werden die Tabellen erstellt.

13
JoshYates1980

EDIT: ASP.NET-Identität mit EF-Datenbank zuerst für MVC5-CodePlex-Projektvorlage.


Ich wollte eine vorhandene Datenbank verwenden und Beziehungen zu ApplicationUser erstellen. So habe ich es mit SQL Server gemacht, aber die gleiche Idee würde wahrscheinlich mit jeder DB funktionieren.

  1. Erstellen Sie ein MVC-Projekt
  2. Öffnen Sie die unter der DefaultConnection in der Datei Web.config aufgeführte Datenbank. Es heißt (aspnet- [timestamp] oder so ähnlich.)
  3. Skripten Sie die Datenbanktabellen.
  4. Fügen Sie die skriptbasierten Tabellen in eine vorhandene Datenbank in SQL Server Management Studio ein.
  5. Passen Sie Beziehungen zu ApplicationUser an und fügen Sie sie hinzu (falls erforderlich).
  6. Neues Webprojekt erstellen> MVC> Erstes DB-Projekt> DB mit EF importieren ... Ausgenommen die von Ihnen eingefügten Identitätsklassen.
  7. Ändern Sie in IdentityModels.cs den ApplicationDbContext :base("DefaltConnection"), um den DbContext Ihres Projekts zu verwenden.

Bearbeiten: Asp.Net-Identitätsklassendiagramm  enter image description here

10
stink

IdentityUser ist hier wertlos, weil es das Code-First-Objekt ist, das von UserStore zur Authentifizierung verwendet wird. Nachdem ich mein eigenes Objekt User definiert hatte, implementierte ich eine Teilklasse, die IUser implementiert, die von der Klasse UserManager verwendet wird. Ich wollte, dass mein Ids int anstelle von string ist, also gebe ich einfach die UserID an String () zurück. Ebenso wollte ich, dass n in Username nicht kapitalisiert wird.

public partial class User : IUser
{

    public string Id
    {
        get { return this.UserID.ToString(); }
    }

    public string UserName
    {
        get
        {
            return this.Username;
        }
        set
        {
            this.Username = value;
        }
    }
}

Sie brauchen auf keinen Fall IUser. Es ist nur eine Schnittstelle, die vom UserManager verwendet wird. Wenn Sie also einen anderen "IUser" definieren möchten, müssen Sie diese Klasse neu schreiben, um Ihre eigene Implementierung zu verwenden.

public class UserManager<TUser> : IDisposable where TUser: IUser

Sie schreiben jetzt Ihr eigenes UserStore, das die gesamte Speicherung von Benutzern, Ansprüchen, Rollen usw. verwaltet. Implementieren Sie die Schnittstellen von allem, was das Code-first UserStore tut und ändert where TUser : IdentityUser bis where TUser : User wobei "Benutzer" Ihr Entitätsobjekt ist

public class MyUserStore<TUser> : IUserLoginStore<TUser>, IUserClaimStore<TUser>, IUserRoleStore<TUser>, IUserPasswordStore<TUser>, IUserSecurityStampStore<TUser>, IUserStore<TUser>, IDisposable where TUser : User
{
    private readonly MyAppEntities _context;
    public MyUserStore(MyAppEntities dbContext)
    { 
        _context = dbContext; 
    }

    //Interface definitions
}

Hier einige Beispiele für einige Schnittstellenimplementierungen

async Task IUserStore<TUser>.CreateAsync(TUser user)
{
    user.CreatedDate = DateTime.Now;
    _context.Users.Add(user);
    await _context.SaveChangesAsync();
}

async Task IUserStore<TUser>.DeleteAsync(TUser user)
{
    _context.Users.Remove(user);
    await _context.SaveChangesAsync();
}

Mit der MVC 5-Vorlage habe ich AccountController so geändert.

public AccountController()
        : this(new UserManager<User>(new MyUserStore<User>(new MyAppEntities())))
{
}

Jetzt sollte die Anmeldung mit Ihren eigenen Tabellen funktionieren.

8
Shoe

Schauen Sie sich dieses Projekt auf GitHub an: https://github.com/KriaSoft/AspNet.Identity

Welches beinhaltet:

  • SQL-Datenbankprojektvorlage für ASP.NET Identity 2.0
  • Entity Framework Database-First-Anbieter
  • Quellcode und Beispiele

enter image description here

Siehe auch : So erstellen Sie einen Database-First-Provider für ADO.NET Identity

3

Ich habe mich mehrere Stunden damit beschäftigt und endlich eine Lösung gefunden, die ich auf meinem Blog geteilt habe hier . Grundsätzlich müssen Sie alles tun, was in der Antwort von stink gesagt wurde, aber mit einer zusätzlichen Sache: Sicherstellen, dass Identity Framework eine spezifische SQL-Client-Verbindungszeichenfolge über der für Ihre Anwendungsentitäten verwendeten Entity Framework-Verbindungszeichenfolge verfügt .

Zusammenfassend wird Ihre Anwendung eine Verbindungszeichenfolge für Identity Framework und eine andere für Ihre Anwendungsentitäten verwenden. Jede Verbindungszeichenfolge hat einen anderen Typ. In meinem Blogbeitrag finden Sie eine vollständige Anleitung.

2
Daniel Eagle

Gute Frage.

Ich bin eher eine Datenbank-First-Person. Das Code-First-Paradigma scheint mir verworren zu sein, und die "Migrationen" scheinen zu fehleranfällig.

Ich wollte das Aspnet-Identitätsschema anpassen und mich nicht um Migrationen kümmern. Ich bin mit Visual Studio-Datenbankprojekten (sqlpackage, data-dude) bestens vertraut und verstehe, wie sich Schemas aufrüsten lassen.

Meine vereinfachende Lösung lautet:

1) Erstellen Sie ein Datenbankprojekt, das das Aspnet-Identitätsschema widerspiegelt. 2) Verwenden Sie die Ausgabe dieses Projekts (.dacpac) als Projektressource. 3) Stellen Sie das .dacpac bei Bedarf bereit

In MVC5 scheint das Ändern der Klasse ApplicationDbContext in Gang zu kommen ...

1) Implementiere IDatabaseInitializer

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDatabaseInitializer<ApplicationDbContext> { ... }

2) Geben Sie im Konstruktor an, dass diese Klasse die Datenbankinitialisierung implementiert:

Database.SetInitializer<ApplicationDbContext>(this);

3) Implementiere InitializeDatabase:

Hier habe ich mich für DacFX entschieden und meinen .dacpac bereitgestellt

    void IDatabaseInitializer<ApplicationDbContext>.InitializeDatabase(ApplicationDbContext context)
    {
        using (var ms = new MemoryStream(Resources.Binaries.MainSchema))
        {
            using (var package = DacPackage.Load(ms, DacSchemaModelStorageType.Memory))
            {
                DacServices services = new DacServices(Database.Connection.ConnectionString);
                var options = new DacDeployOptions
                {
                    VerifyDeployment = true,
                    BackupDatabaseBeforeChanges = true,
                    BlockOnPossibleDataLoss = false,
                    CreateNewDatabase = false,
                    DropIndexesNotInSource = true,
                    IgnoreComments = true,

                };
                services.Deploy(package, Database.Connection.Database, true, options);
            }
        }
    }
2
Aaron Hudon

Ich fand, dass @ JoshYates1980 die einfachste Antwort hat.

Nach einer Reihe von Versuchen und Fehlern tat ich, was Josh vorschlug, und ersetzte die connectionString durch meine generierte DB-Verbindungszeichenfolge. Was mich ursprünglich verwirrte, war der folgende Beitrag:

Hinzufügen der ASP.NET MVC5-Identitätsauthentifizierung zu einer vorhandenen Datenbank

Wobei die akzeptierte Antwort von @Win angab, den ApplicationDbContext() Verbindungsnamen zu ändern. Dies ist etwas vage, wenn Sie Entity und einen Datenbank-/Modell-Ansatz verwenden, bei dem die Datenbankverbindungszeichenfolge generiert und der Datei Web.config Hinzugefügt wird.

Der Verbindungsname ApplicationDbContext() wird der Standardverbindung in der Datei Web.config Zugeordnet . Daher funktioniert Joshs Methode am besten, aber um die Lesbarkeit von ApplicationDbContext() zu verbessern, würde ich vorschlagen, den Namen in den Namen Ihrer Datenbank zu ändern, der ursprünglich als @Win gepostet wurde, und dabei die connectionString für das zu ändern "DefaultConnection" im Web.config Auskommentieren und/oder die Entity generierte Datenbank entfernen.

Codebeispiele:

1
TheSchnitz

Wir haben ein Entitätsmodell DLL Projekt, in dem wir unsere Modellklasse behalten. Wir haben auch ein Datenbankprojekt mit allen Datenbankskripten. Mein Ansatz war wie folgt

1) Erstellen Sie zuerst ein eigenes Projekt mit der EDMX-Datenbank

2) Erstellen Sie ein Skript für die Tabellen in Ihrer Datenbank. Ich habe VS2013 verwendet, das mit localDB (Data Connections) verbunden ist, und das Skript in das Datenbankprojekt kopiert. Fügen Sie benutzerdefinierte Spalten hinzu, z. BirthDate [DATE] ist nicht null

3) Stellen Sie die Datenbank bereit

4) Aktualisieren Sie das Modellprojekt (EDMX). Fügen Sie es dem Modellprojekt hinzu

5) Fügen Sie der Anwendungsklasse benutzerdefinierte Spalten hinzu

public class ApplicationUser : IdentityUser
{
    public DateTime BirthDate { get; set; }
}

Im MVC-Projekt AccountController wurde Folgendes hinzugefügt:

Der Identitätsanbieter möchte, dass eine SQL-Verbindungszeichenfolge funktioniert. Um nur eine Verbindungszeichenfolge für die Datenbank beizubehalten, extrahieren Sie die Anbieterzeichenfolge aus der EF-Verbindungszeichenfolge

public AccountController()
{
   var connection = ConfigurationManager.ConnectionStrings["Entities"];
   var entityConnectionString = new EntityConnectionStringBuilder(connection.ConnectionString);
        UserManager =
            new UserManager<ApplicationUser>(
                new UserStore<ApplicationUser>(
                    new ApplicationDbContext(entityConnectionString.ProviderConnectionString)));
}
1
Haroon