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="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.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 webweb.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: {
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
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
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