40 votes

Comment créer des champs supplémentaires personnalisés dans UserProfile dans MVC4

Je confrontés à de nouvelles ASP net MVC 4 fonctionnalité, il est livré avec l'adhésion de nouveaux membres db schéma et des nouvelles de l'initialisation. Dans mvc 3 et les anciennes versions développeur capable de créer des champs de profils utilisateurs à l'aide de spécifications dans le web.config, mais maintenant, j'ai fait face avec la méthode à filtres espace de noms par défaut mvc 4 projet:

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

et le profil de l'utilisateur table:

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

Mais la méthode InitializeDatabaseConnection générer seul nom d'utilisateur et le nom d'utilisateur j'ai besoin de générer d'autres champs supplémentaires.

J'ai une bonne expérience en EF codeFirst approche, et dans ce cas, j'essaie de modifier UserProfile Classe:

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

Mais quand je régénérer la base de données, je n'ai pas voir tous les changements, Personnalisé Db champs n'est pas généré. Aider moi s'il vous plaît, comment puis-je créer des champs d'utilisateur?

52voto

IMLiviu Points 818

L'élaboration de la réponse ci-dessus

L' WebSecurity.InitializeDatabaseConnection Méthode d'aider les états qui le

Si vous souhaitez utiliser une table de base de données qui contient les informations de profil utilisateur (noms d'utilisateur, adresses e-mail, et ainsi de suite), vous spécifiez une chaîne de connexion et le nom de la table que le système utilise pour se connecter à l'information. Si vous ne souhaitez pas utiliser un profil utilisateur existant table, vous pouvez spécifier que le InitializeDatabaseConnection() la méthode doit créer automatiquement le profil de l'utilisateur table. (Une base de données pour le profil de l'utilisateur le tableau doit déjà exister.)

Donc, si nous voulons plus de champs dans l' UserProfile tableau nous avons juste besoin de nous assurer de la création d'une table de profil et d'exécuter l' InitializeDatabaseConnection méthode une fois que la table est déjà en place.

Dans la norme MVC4.0 modèle de projet de VS2012 j'ai commenté le Compte du contrôleur

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
{

et déplacé InitializeDatabaseConnection dans l'EF Premier Code de Base de données de l'Initialiseur

public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext>
{
    protected override void Seed(MyDatabaseContext context)
    {
        SeedMembership();
    }

    private void SeedMembership()
    {
        WebSecurity.InitializeDatabaseConnection("MyDatabaseContext",
            "UserProfile", "UserId", "UserName", autoCreateTables: true);
    } 
}

veiller à ce que l' InitializeDatabaseConnection s'exécute une fois que la table est déjà en place.

Ajout de la UserProfile classe de mon EF Code Premier modèle

public class MyDatabaseContext : DbContext
{
    public DbSet<UserProfile> UserProfiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

Ajouté le champ supplémentaire dans l' UserProfile tableau

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

Tous vous avez besoin maintenant est de mettre l'initialisation de la base de la stratégie lorsque l'application démarre, et également d'appel d'une requête sur la base de données, assurez-vous qu'il est créé à ce moment, avant toute autorisation/code d'authentification est appelé.

protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();

   WebApiConfig.Register(GlobalConfiguration.Configuration);
   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
   RouteConfig.RegisterRoutes(RouteTable.Routes);
   BundleConfig.RegisterBundles(BundleTable.Bundles);
   AuthConfig.RegisterAuth();

   Database.SetInitializer<MyDatabaseContext>(new MyDatabaseInit());
   new MyDatabaseContext().UserProfile.Find(1);
}

18voto

TrueBlueAussie Points 26794

Non-destructive version basée sur IMLiviu de réponse et commentaires:

Viens de tomber sur ce un problème dû unknot la façon correcte de le faire à partir de la réponse + commentaires (+ essai et erreur), donc pensé que je voudrais partager les résultats que vous pouvez couper et coller. Ceci est basé sur la réponse par IMLiviu, si pleine de crédit pour eux. Il modifie le UserProfile et UserContext les classes telles qu'elles apparaissent directement compatible avec les objectifs EF comme-est:

J'ai été horrifié de voir une suggestion qui a impliqué la suppression complète d'une base de données, juste pour ajouter un peu de tables donc, après avoir lu tous les commentaires et la création d'un prototype, voici le résultat.

1 - Arrêter de Webmatrix création

Arrêt de la norme webmatrix création de l'adhésion des tables (commentaire de la [InitializeSimpleMembership] attribut).

[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller

2 - Créer une configuration de la migration

Créer une configuration de la migration de la classe comme celle ci-dessous:

public class MigrationConfiguration : DbMigrationsConfiguration<UsersContext> 
{
    public MigrationConfiguration()
    {
        this.AutomaticMigrationsEnabled = true;  // This is important as it will fail in some environments (like Azure) by default
    }

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

3 - Retirer la pluralisation de EF création

Modifier la AccountModel.cs fichier UsersContext classe de supprimer la pluralisation de l'option (ajouté le OnModelCreating de l'événement):

public class UsersContext : DbContext
{
    public UsersContext() : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

4 - Ajouter de nouveaux champs à UserProfile

Ajouter des champs supplémentaires, vous devez UserProfile:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string UserEmail { get; set; }  // <<<<<<<< E.G. THIS ADDED
}

5 - Migrer les tables sur app start

Maintenant au démarrage de l'application, vous définissez la base de données d'initialisation de la stratégie et de déclencher à l'aide d'une lecture:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        Database.SetInitializer(new MigrateDatabaseToLatestVersion<UsersContext, MigrationConfiguration>());
        new UsersContext().UserProfiles.Find(1);
    }

Évidemment, vous aurez besoin d'ajouter différentes à l'aide des instructions pour obtenir tout cela fonctionne, mais le clic droit de résoudre option de le faire pour vous.

Notes supplémentaires:

Si vous décidez (comme je l'ai fait) pour utiliser une autre table que UserProfile pour vos utilisateurs, vous avez besoin de changer plusieurs entrées pour le match.

  • Dans votre SimpleMembershipInitializer classe que vous besoin de faire référence à la nouvelle table et les noms de colonne
  • Dans le compte du contrôleur et les différents Login et Enregistrer des vues, vous devez référencer votre nouveau modèle de champs (si les noms ont changé)
  • Dans l' UsersContext classe, vous pouvez laisser le Userprofile classname comme-est, mais vous avez besoin de changer l' Table d'attribut pour correspondre à votre nom de table.
  • Dans l' UserProfile classe, vous devez renommer les champs pour correspondre à votre nouvelle table des noms de champ.
  • Dans la base de données, vous devez retirer la relation entre webpages_UsersInRoles et UserProfile et ajouter une relation entre votre nouvelle table utilisateur et d' webpages_UsersInRoles ou la vieille de l'intégrité référentielle, vérifications de vous briser au moment de l'exécution. (Je vous recommande fortement de supprimer l'existant UserProfile tableau et vérifier qu'il n'est pas recréé. si c'est que vous avez quelque chose à gauche derrière dans votre code).

6voto

CR41G14 Points 1918

Ajoutez une nouvelle table à la base de données et appelez-la User_Details ou similaire. Lors de la création d'un utilisateur, vous pouvez extraire l'ID de l'utilisateur et forcer les détails dans la nouvelle table. C'est une option simple.

3voto

pranav rastogi Points 1426

Consultez le modèle de projet Internet MVC4 fourni avec VS2012 ou VS2010. Vous devez vous assurer que la base de données n'est pas créée avant de modifier les colonnes de votre classe userprofile. vous pouvez ajouter plus de propriétés dans vos classes POCO, puis régénérer votre base de données. si vous ajoutez des propriétés après la génération de la base de données, assurez-vous d'utiliser les migrations EF pour ajouter ces nouvelles propriétés à la base de données.

3voto

yardpenalty Points 90

Bien sûr, vous savez probablement que vous avez à faire votre RegisterModel identiques à UserProfile Model. Ce que j'aime faire est d'utiliser des Migrations avant l'initialisation de la base de données et de mettre ce qui suit dans l' Configuration.cs le fichier:

    protected override void Seed(UsersContext context)
    {

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

        if (!WebSecurity.UserExists("yardpenalty"))
            WebSecurity.CreateUserAndAccount(
                "yardpenalty",
                "password",
                new
                {
                    Email = "youremail@yahoo.com",
                    ImageUrl = "/Content/Avatars/yourname",
                    DateJoined = DateTime.Now
                },
                false);  
           //... rest of model.Builder stuff 
   }

Puis-je utiliser l' Packet Manager Console par ces trois facile à mémoriser des commandes:

  1. Activer-Migrations
  2. Ajoutez-La Migration MigrationName
  3. Mise à jour de la Base de données // va graines de Configuration.cs

Je suis d'accord avec TrueBlueAussie , et serait aller aussi loin que de dire LazyInitialization n'est pas très utile et vous n'avez pas vraiment appeler ça vous a plus. De toute façon, Tout ce que vous avez à faire est de changer alors de vous Inscrire l'Action dans votre Compte Contrôleur d'appeler la Méthode comme ceci:

  WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });

REMARQUE: MVC5 utilise OWIN

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X