Come modellare gli account utente in ASP MVC Framework con Entity Framework usando un approccio code-first?

4

Come progettate il vostro approccio code-in nel framework di entità quando il vostro codice dovrebbe includere dati utente (nome, password ...) senza ripetere / sovrascrivere ciò che il framework MVC genererà in termini di tabelle, classi, autorizzazioni e l'autenticazione

Come semplice esempio, se ho un'applicazione che gestirà i progetti utente, i miei modelli conterranno le seguenti classi e avranno la seguente relazione:

- One user may be assigned one or MANY projects
- One project may be assigned to one or MANY users

(solo per mostrare la natura di relazione ERD da molti a molti)

class User{
    //implementation of the class members and 
    // navigation properties to alow Entity Framework to create the DB tables
}

class Project{
    //implementation of the class members and 
    // navigation properties to alow Entity Framework to create the DB tables
}

Ora il problema che sto affrontando è che il framework EF e ASP .net MVC si occupa della creazione di tabelle utente, profili e ruoli ...

Non sono sicuro se sia possibile progettare le mie classi in modo da mostrare una relazione automatica (convenzionale) con il resto delle tabelle create da MVC.

Nel caso in cui questo debba essere fatto scrivendo classi di Autenticazione personalizzate, puoi spiegare come? perché ho trovato molti articoli che discutono lo stesso problema ma senza evidenziare la relazione tra le classi del progetto e le classi / tabelle MVC create, inoltre se lo sviluppatore sceglie di utilizzare il modo MVC si ritroverà con due contesti dati, anche dopo unendo entrambe le tabelle in un catalogo di server sql.

    
posta joe 29.08.2014 - 18:27
fonte

2 risposte

2

Se sto leggendo la tua domanda correttamente, allora quello che stai cercando è SimpleMembership .

Ecco una spiegazione di SimpleMembership ; dalla sezione Facile con [sic] Entity Framework Code First :

SimpleMembership ... allows[changed] you to use any table as a user store. That means you're in control of the user profile information, and you can access it however you'd like ....

Quindi puoi definire la tua classe User per contenere ulteriori dati e relazioni utente, ad esempio:

[Table("UserProfile")]
public class UserProfile
{
    // required fields:
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int      UserId { get; set; }
    public string   UserName { get; set; }

    // your extra fields:
    public List<Project> Projects { get; set; }
    // more here...
}

e la roba di appartenenza regolare e integrata viene utilizzata per gestire accessi, password e tutto il resto dietro le quinte.

C'è ancora un po 'di più da fare per integrarlo, ma non è stato male quando l'ho usato.

Si noti che questo funziona da MVC4 su.

Modifica per rispondere alle domande poste nei commenti:

Da quello che posso dire guardando il mio codice (è passato un po 'di tempo da quando ho lavorato al progetto e, tra il mio primo progetto MVC e altri progetti che mi scuotevano il cervello da allora, le cose sono un po' confuse):

Sembra che abbia finito per creare il mio contesto ereditato dalla classe DbContext (come delineato in questo tutorial ) e conteneva tutti i miei dati applicativi; per esempio:.

public class MyContext : DbContext
{
    public MyContext()
        : base("DefaultConnection")
    {

    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Projects> Projects { get; set; }
    // more here
}

(IIRC, ereditando dal tipo DbContext otteniamo tutti gli elementi di appartenenza incorporati.)

Quindi il resto dell'app doveva essere configurato per utilizzare questo contesto (come indicato nel tutorial). (Tutti i miei controllori creano un'istanza del mio contesto derivato, ma questo potrebbe essere impostato usando anche l'injection dependency.)

Sembra che la connessione al database sia inizializzata in InitializeSimpleMembershipAttribute per impostazione predefinita - questo attributo viene applicato a tutti i controller.

Mi sono imbattuto nel problema indicato in questa domanda con questa configurazione, quindi per risolverlo ho seguito il consiglio nella risposta accettata e spostato il codice di inizializzazione della connessione al database in un punto centrale (Global.asax.cs) che è stato eseguito una sola volta all'avvio dell'app web.

Ho paura di non ricordare molti più dettagli di questo, quindi probabilmente dovrai fare un po 'più di ricerca (e probabilmente risoluzione dei problemi) per farlo funzionare, ma dovrebbe darti un'idea decente di cosa cercare.

Ho finito per leggere un sacco di tutorial su asp.net , quindi potresti controllare quel sito se non lo hai già fatto .

    
risposta data 04.09.2014 - 16:46
fonte
2

Ecco come puoi realizzare questo.

Ho intenzione di spiegare un modo in cui è possibile utilizzare le tabelle degli account Asp.Net in Mvc, oltre a poter aggiungere ulteriori informazioni in base alle proprie esigenze.

Per prima cosa è necessario installare i seguenti pacchetti.

Install-Package Microsoft.AspNet.Identity
  Install-Package Microsoft.AspNet.Identity.EntityFramework

Ora dovresti procedere ulteriormente come segue.

Prima di tutto Asp.Net Identity fornisce una tabella IdentityUser che contiene le seguenti proprietà

Id, UserName, PasswordHash, SecurityStamp, Discriminatore

Supponiamo di voler aggiungere ulteriori proprietà per poterlo fare creando una classe ed ereditandolo da IdentityUser

Ecco un esempio, diciamo che lo chiamo Client.

public class Client:IdentityUser
{

      //Suppose I want to add Further Properties to to my IdentityUser 
      //table provided by Asp.Net by default.
      //suppose i want Email,Date Birth.

   [Required]
   [Display(Name = "Email")]
   public string Email { get; set; }

   [Required]
   [Display(Name = "BirthDate")]
   public DateTime BirthDate { get; set; }

}


Now Create Your Model classes Lets say in my case One User can have many Projects.



 public class Project
  {


 //Now all your properties will go here
   // plus now you can connect projects to IdentityUser
   //by using Client class which is inherited from IdentityUser.

        public virtual Client Client{get; set;}

   }

Le tue ulteriori classi di modelli andranno qui.

public class  SecondModelClass
   {

   }


Now Go to your context rather than inheriting it from DbContext you can inherit it from  IdentityDbContext   here is sample code below.

//Notice I am passing it Client class which was inherited from IdentityUser

public class YourContextName:IdentityDbContext<Client>
{


    public YourContextName():base("connectionStringName")
    {


    }


    public class IdentityUserLoginConfiguration :      EntityTypeConfiguration<IdentityUserLogin>
    {
        public IdentityUserLoginConfiguration()
        {
            HasKey(iul => iul.UserId);
        }
    }


    public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
    {
        public IdentityUserRoleConfiguration()
        {
            HasKey(iur => iur.RoleId);
        }

    }



    public DbSet<Project> Projects { get; set; }

    public DbSet<ModelClass2> AnyName { get; set; }

    public DbSet<ModelClass3> MoreClassesName { get; set; }




    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration());
        modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration());
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    }





}

Ora è tutto AccountController che dovresti passare la tua classe Client ereditata da IdentityUser

public class AccountController : Controller
{
    public AccountController()
        : this(new UserManager<Client>(new UserStore<Client>(new Context.YourContextName())))
    {
    }

    public AccountController(UserManager<Client> userManager)
    {
        UserManager = userManager;
    }

    public UserManager<Client> UserManager { get; private set; }


  //Further Code Will go below here........................
  //

}

Questa soluzione utilizzerà tutto ciò che è fornito da Asp.Net Identity più la tua personalizzazione.

Saluti.

    
risposta data 06.09.2014 - 05:15
fonte

Leggi altre domande sui tag