34

Ho creato un ASP.NET MVC 5 Applicazione che utilizza Visual Studio 2013 Update 2. Nell'applicazione, ho un controller account. È diverso da quello a cui sono abituato e non contiene un'istanza di dbcontext.In che modo una nuova applicazione ASP.NET MVC 5 sa come creare un database e in che modo l'Account Controller accede al database?

public class AccountController : Controller 
{ 
    private ApplicationUserManager _userManager; 

    public AccountController() 
    { 
    } 

    public AccountController(ApplicationUserManager userManager) 
    { 
     UserManager = userManager; 
    } 

    public ApplicationUserManager UserManager { 
     get 
     { 
      return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

mio web.config che viene creato per impostazione predefinita ha una stringa di connessione come questo:

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

Qualcuno può spiegare a me come l'applicazione sa per creare un database per questa applicazione quando si avvia per la prima tempo?

Inoltre, all'avvio successivo, utilizza Entity Framework per accedere alle tabelle Identity per eseguire l'autenticazione?

+1

Vedere 'IdentityModel.cs' nella cartella' Modelli' nel modello MVC. – Shoe

risposta

79

1) Che cosa sta succedendo qui:

Quando si crea una nuova MVC 5 applicazione e scegliere "Account singolo utente", un nuovo fornitore di ASP.NET Identità è incluso che utilizza Entity Framework 6 Code-First.

Microsoft ha adottato EF-Code-First per rendere Identità come personalizzabile possibile.

quando l'identità si accede per la prima volta, Entity Framework verifica se il database esiste. Se non diversamente configurato, utilizza "DefaultConnection" per trovare il database delle identità. Se il database non esiste quando viene chiamato Identity, EF crea automaticamente il database.

Avviso la stringa di connessione contiene

`AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf` 

Se si apre il App_Data cartella, si dovrebbe avere un file aspnet-WebApplication3-20140417072624.mdf.

Se si fa doppio clic su questo file mdf, il VS2013 Esplora server aprirà il vostro DB. Se si è già tentato di accedere a qualsiasi funzionalità di identità, si queste tabelle creato:

  • _MigrationHistory
  • ASPNetRoles
  • ASPNetUserClaims
  • ASPNetUserLogins
  • ASPNetUsers

Per impostazione predefinita, la vostra applicazione è configurato per utilizzare SQL Server Compact (file MDF) in modo da non avere un vero e proprio SQL Server Istanza in esecuzione. Tutto questo è personalizzabile. Il nome del file MDF, lo schema di identità del database, la scelta di SQL Compact vs un vero e proprio SQL Server esempio. Cambia la tua stringa di connessione, o creane una nuova e passa questa nuova connessione al tuo contesto.


2) DOVE SI TROVA IL MIO CONTESTO?

Tutto questo è molto bello, ma una domanda importante che hai chiesto è fondamentalmente "Dove è il mio contesto?", e le altrettanto rilevanti domande implicite per quanto riguarda come è possibile personalizzare ulteriormente il vostro DB o alterare la logica di convalida.

Si noterà che il progetto fa riferimento a Microsoft.AspNet.Identity.EntityFramework. Questo assembly è un'implementazione di IdentityDBContext<TUser> e l'impianto della classe UserManager.

Aprire il AccountController, e notare il costruttore ha UserManager oggetto passato che a sua volta ha un oggetto new UserStore passato, che viene approvato una ApplicationDbContext.

public AccountController() 
     : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) 

Il ApplicationDbContext è definito nei tuoi modelle cartella. All'interno di tale cartella, troverai un file IdentityModels.cs. Aprilo e vedrai

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext() 
     : base("DefaultConnection") 
    { 
    } 
} 

Qui è dove viene assegnato il tuo contesto di identità. è possibile modificare il nome della connessione passato al costruttore ApplicationDbContext oppure definire e utilizzare un contesto diverso nel controller dell'account.


3) Come faccio a personalizzare MIO SCHEMA identità?

Un'altra classe definita in IdentityModels.cs file è la classe che eredita da ApplicationUserIdentityUser classe.

public class ApplicationUser : IdentityUser 
{ 
} 

Qualsiasi proprietà che si aggiungono a questa classe saranno persistenti nei vostri ASPNetUsers Table. Il resto dello schema è definito nella classe IdentityDbContext. Così, mentre è possibile aggiungere più tabelle (ad esempio privilegi) allo schema di identità con l'aggiunta di un DBSet alla definizione del contesto,

public DBSet<Privileges> { get; set; } 

alterare altre tabelle (ruoli, reclami, ecc) è anche possibile, ma molto più coinvolto . Ad esempio, per personalizzare la tabella Roles, è necessario implementare un NewIdentityRole ereditato da IdentityRole e aggiungere la relazione sostituendo il metodo OnModelCreating() per il proprio contesto.

Questo articolo su Customizing Roles Tables fa un buon lavoro di descrizione dei passaggi coinvolti. Anche qui, scoprirai che ci sono grossi problemi investiti semplicemente nell'aggiungere nuove colonne. La rimozione di tabelle o colonne dallo schema originale creato nella classe IdentityDbContext è probabilmente tanto problematica quanto la creazione della propria implementazione della classe IdentityDbContext.

+1

Dave. Grazie per il tuo aiuto e i tuoi consigli. Ho verificato e alcune delle tue spiegazioni non si applicano più agli ultimi modelli utilizzati con MVC5 e VS2013 Update 2. Questa combinazione utilizza ASP.NET Identity 2 ma penso che alcune delle tue spiegazioni si riferiscano al vecchio modello di identità. – Melina

+0

@ Melina, per favore espanderlo. Ho descritto l'ambiente in cui sono presente e penso che abbia tutti gli ultimi aggiornamenti di nuget. Se sono accaduti degli anticipi di cui non sono a conoscenza, mi piacerebbe capire di più ... –

+4

Ho appena controllato un po 'di più su ciò che offre l'RC per l'aggiornamento 2 e penso che starò lontano da questo per un po'. Per quanto posso vedere, sembra che il controller dell'account non sia finito. Hanno apportato molte modifiche al controller dell'account ma sembra che manchi di un metodo di accesso e quando avvio la stessa applicazione non ci sono collegamenti "login" o "registrati" per fare clic. Sembra che RC sia un WIP :-(Accetterà la tua risposta in quanto si applica a ciò che la maggior parte delle persone sta usando.Grazie – Melina

0

Sicuramente sarebbe nel ApplicationUserManager, La mia ipotesi è che questo è un servizio che utilizza il contesto db per gestire gli utenti dell'applicazione.

È possibile fare clic con il pulsante destro su questa classe e fare clic su Go to definition e continuare a farlo finché non è possibile visualizzare la classe che inizializza il database.

Inoltre, in MVC 4 l'inizializzazione viene eseguita in un attributo di filtro. Quindi cerca nella cartella Filtro se ce n'è una. So che non è MVC 5. Ma potrebbe ancora essere applicabile.

0

Come ha sottolineato Melina, la domanda originale faceva riferimento al modello di identità 2.x di ASP.NET corrente.

risposta fornito preziose informazioni sfondo di Dave Alperovich sui concetti che stanno dietro ASP.NET Identità, anche se gli esempi sono stati elaborati da 1.x ASP.NET identità, che è stato sostituito nel 2014.

Callum Linington fornisce la "insegnare un uomo da pescare "rispondi. Seguendo il suo consiglio, è facile vedere che la 2.x "ApplicationUserManager" è derivata da uno "UserManager" in stile 1.x.

La risposta è fondamentalmente che il "ApplicationUserManager", che viene iniettato come parametro quando viene creata "AccountController", si connette all'archivio dati identità nel proprio costruttore:

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 

Nota come questo "nascosto "Il codice 2.x è molto simile al 1.x codice come indicato sopra:

public AccountController() 
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))