2012-09-10 2 views
19

Ho un sito ASP.NET MVC 4 basato sul modello Internet. Sto usando SimpleMembership che ho impostato con quel modello.Come posso gestire i profili usando SimpleMembership?

Posso modificare la tabella Utenti che è stata elaborata per me, ma non sono sicuro del modo "corretto" per modificare i campi aggiuntivi che ho aggiunto. Voglio Fullname, Email ecc. E li ho aggiunti alla tabella degli utenti, ma non sembra che sia possibile aggiornarli tramite i metodi statici di SimpleMembership WebSecurity.

Si suppone di aggiornare semplicemente tali proprietà utilizzando EF all'esterno dell'API SimpleMembership?

risposta

4

se si guarda a destra intorno alla linea 273 del accountcontroller troverete questa linea

db.UserProfiles.Add(new UserProfile { UserName = model.UserName }); 

Sembra anche che OOTB (MS) stanno facendo proprio come lei ha suggerito e l'utilizzo di EF per aggiornare.

Anch'io, sto cercando il modo "corretto" di aggiornare e accedere a queste proprietà.

Edit:

Ecco la mia soluzione (io sono felice se qualcuno dice che non c'è un modo per fare questo OOTB).

avvolgere UserProfile (l'entità .net da SimpleMembership) in una classe di sessione.

public static class sessionHelpers { 
    public static UserProfile userProfile 
     { 
      get 
      { 
       if (HttpContext.Current.Session["userProfile"] != null) 
       { 
        return HttpContext.Current.Session["userProfile"] as UserProfile; 
       } 
       else 
       { 
        using (UsersContext db = new UsersContext()) 
        { 
         HttpContext.Current.Session["userInfo"] = 
         db.UserProfiles.Where(x => x.UserName == 
          HttpContext.Current.User.Identity.Name).FirstOrDefault(); 

        return db.UserProfiles.Where(x => x.UserName == 
         HttpContext.Current.User.Identity.Name).FirstOrDefault(); 
        } 
       } 
      } 
      set { HttpContext.Current.Session["userProfile"] = value; } 
     } 
} 

Da questo si può accedere alla tabella di profilo facendo

string foo = sessionHelpers.userProfile.FIELDNAME; 

dove sessionHelpers è la mia classe wrapper. Il blocco if si limita a garantire che se non è stato impostato nella sessione corrente, accedervi tenterà di ottenerlo.

+2

hmmm ... ho percepito un certo odore di codice serio qui ... stai combinando codice di accesso DB con codice web. Raccomando vivamente di refactoring TUTTI i riferimenti di strutture di entità in un progetto di accesso ai dati isolato, quindi utilizzando il modello di repository per consentire ai chiamanti di recuperare i dati per l'app. –

+0

Con questo modello, come si assicura che le modifiche al profilo vengano riscritte nel database? –

+0

Vorrei trasmettere ciò che è nella sessione a UserProfile piuttosto che usare la parola chiave 'as'. Se accidentalmente inserisci un altro tipo, il tuo getter restituirà * null *. È meglio fallire immediatamente di provare e diagnosticare problemi a valle causati da un profilo utente nullo. –

15

Hanno semplificato la modifica del profilo con SimpleMembership. SimpleMembership utilizza il codice prima del modello EF e il profilo utente è definito nel file AccountModels.cs che viene generato come parte del modello Internet per MVC 4. Basta modificare la classe UserProfile e aggiungere i nuovi campi nella definizione della classe. Ad esempio, l'aggiunta di un campo per la posta elettronica sarebbe simile a questa:

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

Ecco un esempio di come si dovrebbe accedere al campo e-mail:

var context = new UsersContext(); 
var username = User.Identity.Name; 
var user = context.UserProfiles.SingleOrDefault(u => u.UserName == username); 
var email = user.Email; 

Ecco ciò che il database si presenta come dopo l'aggiunta il campo email

enter image description here

C'è un buon blog che descrive alcuni dei changes in SimpleMembership here. È inoltre possibile trovare informazioni più dettagliate su customizing and seeding SimpleMembership here.

+0

due domande da quello però. 1) l'aggiunta di una proprietà qui ha cambiato automaticamente il DB? e come ottenere l'email dell'utente attualmente connesso dall'API? (assumendo le proprietà sopra) – Eonasdan

+0

Cambierà lo schema del DB alla creazione, quindi sarà necessario rimuovere qualsiasi DB esistente affinché funzioni. Ho aggiornato la risposta per mostrare che avresti accesso all'e-mail. Non è un'API come il vecchio MembershipProvider. –

+0

ok, quindi è quello che pensavo. – Eonasdan

22

1 - È necessario abilitare le migrazioni, prefereably con EntityFramework 5

2 - Sposta il tuo

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

al tuo metodo di Seed nella classe YourMvcApp/Migrazioni/Configuration.cs

protected override void Seed(UsersContext context) 
    { 
     WebSecurity.InitializeDatabaseConnection(
      "DefaultConnection", 
      "UserProfile", 
      "UserId", 
      "UserName", autoCreateTables: true); 

     if (!Roles.RoleExists("Administrator")) 
      Roles.CreateRole("Administrator"); 

     if (!WebSecurity.UserExists("lelong37")) 
      WebSecurity.CreateUserAndAccount(
       "lelong37", 
       "password", 
       new {Mobile = "+19725000000", IsSmsVerified = false}); 

     if (!Roles.GetRolesForUser("lelong37").Contains("Administrator")) 
      Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"}); 
    } 

Ora EF5 si occuperà della creazione della tua tabella UserProfile, dopodiché chiamerai WebSecurity.InitializeDatabaseConnection per registrare solo SimpleMembershi pProvider con la tabella UserProfile già creata, anche per diramare SimpleMembershipProvider quale colonna è UserId e UserName. Sto anche mostrando un esempio di come è possibile aggiungere Utenti, Ruoli e associare i due al metodo Seed con proprietà/campi UserProfile personalizzati ad es. Mobile dell'utente (numero) e IsSmsVerified.

3 - Ora, quando si esegue update-database dal Console Package Manager, EF5 sarà disposizione la vostra tavola con tutte le vostre proprietà personalizzate

Per ulteriori riferimenti si prega di fare riferimento a questo articolo con codice sorgente: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

+0

Bello ... mi ha davvero aiutato a risolvere una situazione davvero difficile. :) Maggiori informazioni su questo argomento: http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4- 5-web-forms-and-asp-net-mvc-4-templates.aspx –

+6

presuppone che si stia utilizzando il codice DEMOWARE dal modello Internet. In un'app per il mondo reale, avresti le dipendenze EF in un progetto di accesso ai dati e probabilmente non vorrai che dipenda dagli assembly WebMatrix o da System.Web. –

+0

Concordo, ma come si fa a utilizzare Webmatrix nel progetto di accesso ai dati? – nportelli

1

È necessario aggiungerli al proprio database (fatto secondo la descrizione)

aggiungerli alla vista (modificare, aggiungere, eliminare e visualizzare) se non modificato

aggiungili al tuo modello in UserProfiles

Quindi funzionerà.