87 votes

ASP.NET Identity avec EF Database First MVC5

Est-il possible d'utiliser le nouveau Asp.net Identity avec Database First et EDMX? Ou seulement avec Code First?

Voici ce que j'ai fait:

1) J'ai créé un nouveau projet MVC5 et j'ai utilisé le nouveau Identity pour créer les nouvelles tables Utilisateurs et Rôles dans ma base de données.

2) Ensuite, j'ai ouvert mon fichier EDMX Database First et j'ai fait glisser la nouvelle table Utilisateurs de Identity car j'ai d'autres tables qui y sont liées.

3) En enregistrant l'EDMX, le générateur de POCO Database First va automatiquement créer une classe Utilisateur. Cependant, UserManager et RoleManager attendent une classe Utilisateur héritant de l'espace de noms Identity (Microsoft.AspNet.Identity.IUser), donc utiliser la classe Utilisateur POCO ne fonctionnera pas.

Je suppose qu'une solution possible serait de modifier mes classes de génération de POCO pour que ma classe Utilisateur hérite d'IUser?

Ou ASP.NET Identity est-il uniquement compatible avec la conception Code First?

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

Mise à jour: Suivant la suggestion d'Anders Abel ci-dessous, voici ce que j'ai fait. Cela fonctionne, mais je me demande s'il y a une solution plus élégante.

1) J'ai étendu ma classe Utilisateur d'entité en créant une classe partielle dans le même espace de noms que mes entités générées automatiquement.

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

2) J'ai changé mon DataContext pour qu'il hérite de IdentityDBContext au lieu de DBContext. Notez que chaque fois que vous mettez à jour votre EDMX et régénérez les classes DBContext et Entity, vous devrez revenir à cela.

 public partial class MVC5Test_DBEntities : IdentityDbContext  //DbContext

3) Dans votre classe Entité Utilisateur générée automatiquement, vous devez ajouter le mot-clé override aux 4 champs suivants ou commenter ces champs car ils sont hérités de IdentityUser (étape 1). Notez que chaque fois que vous mettez à jour votre EDMX et régénérez les classes DBContext et Entity, vous devrez revenir à cela.

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

16voto

Anders Abel Points 36203

Il devrait être possible d'utiliser le système d'identité avec POCO et Database First, mais vous devrez apporter quelques ajustements :

  1. Mettez à jour le fichier .tt pour la génération de POCO afin de rendre les classes d'entité partielles. Cela vous permettra de fournir une implémentation supplémentaire dans un fichier séparé.
  2. Créez une implémentation partielle de la classe User dans un autre fichier

    partial User : IUser { }

Cela fera en sorte que la classe User implémente la bonne interface, sans toucher aux fichiers générés (modifier les fichiers générés est toujours une mauvaise idée).

13voto

JoshYates1980 Points 137

Mes étapes sont très similaires mais je voulais partager.

1) Créez un nouveau projet MVC5

2) Créez un nouveau Model.edmx. Même s'il s'agit d'une nouvelle base de données et qu'elle ne contient pas de tables.

3) Modifiez le web.config et remplacez cette chaîne de connexion générée :

avec cette chaîne de connexion :

Ensuite, compilez et exécutez l'application. Inscrivez un utilisateur et les tables seront créées.

10voto

stink Points 412

EDIT: ASP.NET Identity avec EF Database First pour le modèle de projet MVC5 CodePlex.


Je voulais utiliser une base de données existante et créer des relations avec ApplicationUser. Voici comment je l'ai fait en utilisant SQL Server mais la même idée fonctionnerait probablement avec n'importe quelle BD.

  1. Créez un projet MVC
  2. Ouvrez la BD répertoriée sous DefaultConnection dans Web.config. Elle s'appellera (aspnet-[timestamp] ou quelque chose comme ça.)
  3. Scriptez les tables de la base de données.
  4. Insérez les tables scriptées dans une base de données existante dans SQL Server Management Studio.
  5. Personnalisez et ajoutez des relations à ApplicationUser (si nécessaire).
  6. Créez un nouveau projet Web > MVC > Projet DB First > Importez la BD avec EF ... En excluant les classes d'identité que vous avez insérées.
  7. Dans IdentityModels.cs, changez le ApplicationDbContext :base("DefaltConnection") pour utiliser le DbContext de votre projet.

Edit: Diagramme de classe Asp.Net Identity Description de l'image ici

8voto

Shoe Points 2917

En aucun cas je ne pense que c'est la solution la plus efficace, mais cela pose les bases pour cette approche.

IdentityUser est inutile ici car c'est l'objet de code-first utilisé par le UserStore pour l'authentification. Après avoir défini mon propre objet User, j'ai implémenté une classe partielle qui implémente IUser qui est utilisée par la classe UserManager. Je voulais que mes Id soient des int au lieu de string donc je retourne le toString() de l'UserID. De même je voulais que n dans Username soit en minuscules.

public partial class User : IUser
{

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

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

Vous n'avez aucun besoin de IUser. C'est juste une interface utilisée par le UserManager. Donc si vous voulez définir un "IUser" différent vous devrez réécrire cette classe pour utiliser votre propre implementation.

public class UserManager : IDisposable where TUser: IUser

Vous devez maintenant écrire votre propre UserStore qui gère le stockage des utilisateurs, des claims, des rôles, etc. Implémentez les interfaces de tout ce que fait le UserStore code-first et changez where TUser : IdentityUser en where TUser : User où "User" est votre objet entity.

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

    //Définitions d'interfaces
}

Voici quelques exemples d'implémentations d'interfaces

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

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

En utilisant le template MVC 5, j'ai modifié AccountController pour ressembler à ceci.

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

Maintenant la connexion devrait fonctionner avec vos propres tables. Si quelqu'un a des suggestions pour améliorer cela. Ajoutez un commentaire et je le mettrai ici.

3voto

Konstantin Tarkus Points 16862

Jetez un œil à ce projet sur GitHub : https://github.com/KriaSoft/AspNet.Identity

Qui comprend :

  • Modèle de projet de base de données SQL pour ASP.NET Identity 2.0
  • Fournisseur(s) de base de données Entity Framework en mode base de données
  • Code source et exemples

entrer la description de l'image ici

Voir aussi : Comment créer un fournisseur en mode base de données pour ADO.NET Identity

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X