8

Ho un modello EDMX database-first in una libreria separata (ad esempio Common.Feedback.Data), che include la tabella AspNetUser e le relative tabelle di Identity Framework (estratte da un'altra banca dati/applicazione esistente esistente).Cosa associa ApplicationUser alla tabella aspnetusers in Database First?

Ho aggiornato la stringa di connessione ApplicationDbContext per puntare al nuovo modello e la nuova connessione al database:

using System.Data.Entity; 
using System.Security.Claims; 
using System.Threading.Tasks; 
using Microsoft.AspNet.Identity; 
using Microsoft.AspNet.Identity.EntityFramework; 

namespace Feedback.MvcApplication.Models 
{ 
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 

    public class ApplicationUser : IdentityUser 
    { 
     public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
     { 
      // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
      var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
      // Add custom user claims here 
      return userIdentity; 
     } 
    } 

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
    { 
     public ApplicationDbContext() 
      : base("FeedbackEntities", throwIfV1Schema: false) 
     { 
     } 

     public static ApplicationDbContext Create() 
     { 
      return new ApplicationDbContext(); 
     } 
    } 
} 

La stringa di connessione nel web.config include il percorso completo per il montaggio e che il riferimento va bene:

<add name="FeedbackEntities" 
    connectionString="metadata=res://Common.Feedback.Data/FeedbackModel.csdl|res://Common.Feedback.Data/FeedbackModel.ssdl|res://Common.Feedback.Data/FeedbackModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user [email protected];password=mypassword;MultipleActiveResultSets=True;App=EntityFramework&quot;" 
    providerName="System.Data.EntityClient" /> 

in fase di esecuzione, qualsiasi accesso al login risultati nel seguente errore:

"The entity type ApplicationUser is not part of the model for the current context"

Tutti i link che ho provato, relativi a quell'errore, di solito comportano modi di aggiornare la migrazione.

Non è possibile abilitare le migrazioni poiché si tratta di una prima installazione EDMX, ma presumo che ci sia un legame tra l'oggetto ApplicationUser e la tabella aspnetusers "da qualche parte" dietro le quinte.

Qualcuno qui ha una chiara comprensione di come la classe ApplicationUser è mappata su/dalla tabella aspnetusers in fase di esecuzione e spiega come far funzionare il mio codice con il database?

Repro passi

  • Creare una nuova applicazione Web MVC utilizzando VS 2013
  • aggiornare tutti i pacchetti Nuget all'ultima
  • Prendete un database SQL esistente con le tabelle Identity Framework e copiarlo in una nuova tabella (elimina eventuali tabelle non correlate).
  • Aggiungere nuove tabelle per il progetto
  • Creare una libreria di classi per contenere i modelli di dati (ad esempio Common.Feedback.Data)
  • aggiungere un modello di dati EDMX, alla biblioteca, sulla base del database creato in precedenza
  • Cambiate la connessione stringa per qualificare completamente l'assembly (non res://*/)
  • Modificare il nome della stringa di connessione in IdentityModel.cs in modo che corrisponda al nome della stringa di connessione nella configurazione.
  • copiare la stringa di connessione dal di biblioteca app.config a quello del progetto web web.config
  • Prova login e vi ha colpito l'errore menzionato

Aggiornamento:

Sulla base di un post randagio, ho cambiato la mia stringa di connessione corrisponde alla normale connessione SQL che Identity Framework è configurata per l'utilizzo predefinito (e utilizzando un client Sql):

<add name="FeedbackSql" 
    connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user [email protected];password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" 
    providerName="System.Data.SqlClient" /> 

e cambiato in configurazione Per utilizzare il nuovo collegamento:

public ApplicationDbContext() 
     : base("FeedbackSql", throwIfV1Schema: false) 
    { 
    } 

Stranamente i cambiamenti di errore a:

The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.

penso che il cambiamento iniziale a un provider di SqlClient è corretta, quindi questo nuovo errore potrebbe essere correlato all'utilizzo di un database Azure su quella connessione. Sono aperto a suggerimenti su cosa provare dopo.

web.config Aggiornato basa su suggerimento di @rism e this link (ma l'errore persiste GZip):

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> 
     <parameters> 
     <!--<parameter value="mssqllocaldb" />--> 
     <parameter value="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=myuserid;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    </entityFramework> 

Anche in questo caso sulla base di suggerimenti da @rism Ho anche provato questa versione (ma l'errore persiste GZip) :

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v12.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    </entityFramework> 

nuovo aggiornamento:

ho creato una nuova applicazione Web con lo standard sicurezza utente opzione. Ho anche creato un database vuoto in Azure.

ho fatto altro che modificare la stringa di connessione predefinita a questo:

<connectionStrings> 
    <add name="DefaultConnection" 
     connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" 
     providerName="System.Data.SqlClient" /> 
    </connectionStrings> 

e la fabbrica di connessione predefinita a questo:

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v12.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    </entityFramework> 

sul tentativo di login ricevo il seguente errore:

The magic number in GZip header is not correct. Make sure you are passing in a GZip stream. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.InvalidDataException: The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.

Source Error:

Line 153: { Line 154: var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; Line 155: var result = await UserManager.CreateAsync(user, model.Password); Line 156: if (result.Succeeded) Line 157: {

+1

Se si sta percorrendo il percorso di una soluzione DB-first non c'è motivo di rimanere con 'ApplicationDbContext'. Potresti semplicemente rimuovere tutta quella spazzatura, avere il tuo DbContext e risparmiarti un mal di testa – Shoe

+0

Hai appena mostrato il costruttore per ApplicationDbContext() puoi mostrare l'intera classe. Inoltre quale versione di Identity stai usando? La versione 1.0 è molto diversa dalla versione 2. I mapping sono fatti tra classi e tabelle tramite sottoclassi di EntityTypeConfiguration in cui si impostano aspetti del modello come la mappatura dell'integrità referenziale, cardinalità ecc. Se si stava usando Fluent Api in una TspIdentityMap: EntityTypeConfiguration si farebbe una dichiarazione come this.ToTable ("AspNetUsers"); cioè mappare l'entità della classe di codice TspIdentity alla tabella db. – rism

+0

Il motivo per cui voglio vedere l'intero ApplicationDbContext è che il messaggio mi viene letto come se non avessi un DbSet sul tuo contesto che normalmente genererei un errore del compilatore ... ma poi hai mescolato e bit abbinati in modo da poter vedere lo stesso. Controlla anche che stai usando la stessa versione di Identity in tutti i progetti. – rism

risposta

11

La domanda iniziale riguardava come OWIN mappare ilClassealla tabella AspNetUsers.

Ho decompilato le DLL di Identity Framework con DotPeek e ho rilevato che il nome della tabella "AspNetUsers" è semplicemente cablato nel codice del metodo OnModelCreating. per esempio.

protected virtual void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     if (modelBuilder == null) 
     throw new ArgumentNullException("modelBuilder"); 
     EntityTypeConfiguration<TUser> typeConfiguration1 = ((EntityTypeConfiguration<TUser>) modelBuilder.Entity<TUser>()) 
     .ToTable("AspNetUsers"); 

Questo codice utilizza la riflessione per generare un elenco di nomi di campo dalle proprietà a ApplicationUser. Verifica l'esistenza di tutti i nomi dei campi utilizzando una semplice query SQL (della tabella di sistema contenente tutti i nomi dei campi) e conferma che sono tutti presenti.

Il resto è una semplice mappatura di nomi/valori utilizzando query SQL costruite.

Per quanto riguarda l'altra parte del problema, la connessione al database, ho creato una nuova domanda in quanto è a) estranea al titolo di questo e b) mi fa impazzire! La nuova domanda è Why am I getting "The magic number in GZip header is not correct." error using OWIN auth against Azure SQL

Problemi correlati