14

Sto cercando di estendere i dati utente di identità in una tabella separata ma non è popolata.utente di identità personalizzato e profilo di estensione MVC

public class MyUserInfo 
    { 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    } 

    public class AppUser : IdentityUser<Int32, AppUserLogin, AppUserRole, AppUserClaim> 
    { 

    public MyUserInfo MyUserInfo { get; set; } 
} 

//Fetching the user data 

var userStore = new UserStore<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>(db); 
var userManager = new UserManager<AppUser, int>(userStore); 

var user = userManager.FindById(1); 

user.MyUserInfo mostra la null. Ma in db, abbiamo i rispettivi dati utente.

Ho visto molti post in cui senza la personalizzazione sembra funzionare ma per me ho modificato l'ID memorizzato come numero intero e ho cambiato il nome della tabella.

+0

È tutto questo il codice relativo? perché il framework di entità non creerà alcuna relazione tra tabelle come questa – tmg

+0

Non è proprio così semplice ... ma puoi facilmente creare un CustomMembershipProvider che corrisponde alle tue tabelle esistenti ecc. Ne vale la pena, imho. https://logcorner.wordpress.com/2013/08/29/how-to-configure-custom-membership-and-role-provider-using-asp-net-mvc4/ – Robert

+0

@Robert stai parlando di vecchio 'MembershipProvider 'e la domanda riguarda il nuovo framework Identity, e questi non sono gli stessi. – trailmax

risposta

1

Penso che il problema qui non sia strettamente legato all'identità di asp.net ma al framework di entità. Dato che si ottengono dati da userManager.FindById(1) ma non si ottengono i dati relativi dalla tabella MyUserInfo, la relazione non esiste.

Change MyUserInfo entità

public class MyUserInfo 
{ 
    //change it from Id to AppUserId 
    public int AppUserId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    //add this virtual property 
    public virtual AppUser User { get; set; } 
} 

Quindi aggiungere le migrazioni e aggiornamento del database. Il framework Entity renderà la relazione tra le tabelle e AppUserId sarà la chiave esterna (codice prima convenzione di relazione).

+0

la mia ipotesi era la stessa in precedenza ma ricevendo errore con la migrazione: "Impossibile determinare la fine principale di un'associazione tra i tipi" App.Data.Entities.AppUser "e" App.Data.Entities.MyUserInfo ". La fine principale di questa l'associazione deve essere configurata in modo esplicito utilizzando l'API della relazione fluente o le annotazioni dei dati. " – Parwej

+0

la sua struttura di entità causa non può decidere quale MyUserInfo.Id o AppUser.Id è il primario e quale è la chiave esterna, hai provato a rinominare come ho fatto? – tmg

+0

Ho provato ** public class MyUserInfo { [Key, ForeignKey ("User")] public int AppUserId {get; impostato; } public string FirstName {get; impostato; } public string LastName {get; impostato; } Utente appUser pubblico virtuale {get; impostato; } } ** – Parwej

5

Lo stock Identity UserManager non tira automaticamente UserInfo (o qualsiasi altra tabella Entità con stranieri tasto di navigazione)

Hai esteso il Identità schema, ma non hanno esteso la UserManager.

Nessuno dei UserManager 's metodi per ottenere utente (ad esempio findbyid(), FindByIdAsync()) recuperare "bambini" entità di Entity Framework di navigazione.

Date un'occhiata al GitHub FindByIdAsync

public virtual Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) 
    { 
     cancellationToken.ThrowIfCancellationRequested(); 
     ThrowIfDisposed(); 
     var id = ConvertIdFromString(userId); 
     return Users.FirstOrDefaultAsync(u => u.Id.Equals(id), cancellationToken); 
    } 

Il metodo restituisce solo l'impresa utilizzatrice. Non ci sono funzionalità per controllare le tabelle di navigazione "figlio", per non parlare di estrarle.


È possibile estendere la UserManager implementando un tale metodo.

In caso contrario, sarà necessario estrarre manualmente l'entità figlio dopo aver recuperato lo UserId.Ecco come ho fatto:

  var UserId = User.Identity.GetUserId<int>(); 

      try 
      { 
       user = await UserManager.FindByIdAsync(UserId); 
      } 
      catch (Exception e) 
      { 
       return BadRequest(e.Message); 
      } 

      var userInfo = AuthContext.UserInfo. 
        FirstOrDefault(u => u.Id == user.UserInfo_Id); 

Nota: ho dovuto anche fare in modo che il mio ApplicationUser aveva una chiave esterna per il mio UserInfo Entity:

public class ApplicationUser : IdentityUser 
{ 
    [ForeignKey("UserInfo")] 
    public int UserInfo_Id { get; set; } 

    public virtual UserInfo UserInfo { get; set; } 

e nel mio modellista

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<ApplicationUser>() 
      .HasRequired<UserInfo>(profile => profile.UserInfo); 


     base.OnModelCreating(modelBuilder); 
    } 
+1

Sono d'accordo con te. UserManager non estrarrà automaticamente MyUserInfo. Ma penso che sia necessario modificare User.Identity.GetUserId() in User.Identity.GetUserId () poiché pk è int. –

+0

@MohamedRozza, buona presa. Non me ne sono accorto! –

+0

@DaveAlperovich prima di tutto grazie mille per il tuo tempo. Sì, ho letto la tua risposta e ho fatto le stesse cose. Ma la mia preoccupazione era che dovrebbe popolare automaticamente come da questo blog ms http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in -vs-2013-templates.aspx. Ad ogni modo, come suggerimento non dovrebbe essere così in caso di personalizzazione. Grazie ancora per il tuo tempo. – Parwej

Problemi correlati