如何在MVC4中的UserProfile中创build自定义附加字段

我面临着新的ASP MVC 4function,它附带了新的成员资格数据库模式和新的初始化。 在mvc 3和旧版本中,开发人员能够使用web.config中的规范创build自定义用户configuration文件字段,但现在我面临默认mvc 4项目中的filter名称空间中的方法:

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

和用户configuration文件表:

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

但是,方法InitializeDatabaseConnection只生成UserName和UserId我需要生成其他额外的字段。

我在EF codeFirst方法有很好的经验,在这种情况下,我尝试编辑UserProfile类:

 [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; } } 

但是,当我重新生成数据库,我没有看到任何更改,自定义Db字段不生成。 请帮助我,我如何创build自定义用户字段?

从上面的答案详细阐述

WebSecurity.InitializeDatabaseConnection方法帮助说明

如果要使用包含用户configuration文件信息(用户名,电子邮件地址等)的数据库表,则可以指定成员资格系统用来连接到该信息的连接string和表名。 如果您不想使用现有的用户configuration文件表,则可以指定InitializeDatabaseConnection()方法应自动创build用户configuration文件表。 (用户configuration文件表的数据库必须已经存在。)

所以,如果我们需要更多的字段到UserProfile表中,我们只需要确保我们正在创build一个configuration文件表,并在表已经就位后运行InitializeDatabaseConnection方法。

在VS2012的标准MVC4.0项目模板中,我已经注释了帐户控制器

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

并将InitializeDatabaseConnection移入EF Code First数据库初始化程序

 public class MyDatabaseInit: DropCreateDatabaseAlways<MyDatabaseContext> { protected override void Seed(MyDatabaseContext context) { SeedMembership(); } private void SeedMembership() { WebSecurity.InitializeDatabaseConnection("MyDatabaseContext", "UserProfile", "UserId", "UserName", autoCreateTables: true); } } 

确保在表已经就位时运行InitializeDatabaseConnection

UserProfile类添加到我的EF Code First模型中

 public class MyDatabaseContext : DbContext { public DbSet<UserProfile> UserProfiles { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } } 

UserProfile表中添加了额外的字段

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

现在您只需要在应用程序启动时设置数据库初始化策略,并在调用授权/validation代码之前调用数据库查询,确保在此时创build数据库。

 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); } 

基于IMLiviu的回答和评论的非破坏性版本:

刚刚遇到这个问题,不得不从结果+评论(+试验和错误)正确的方式做到这一点,所以我想分享你可以剪切和粘贴的结果。 这是基于IMLiviu的回答,对他们充分的信任。 它修改了现有的UserProfileUserContext类,因为它们直接与EF直接兼容:

我很惊讶地看到一个build议,涉及完全删除数据库,只是添加几个表,所以在阅读所有的评论和创build一个原型后,结果如下。

1 – 停止创buildWebmatrix

停止成员表的标准webmatrix创build(注释[InitializeSimpleMembership]属性)。

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

2 – 创build迁移configuration

创build一个迁移configuration类,如下所示:

 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 – 从EF创build删除多元化

更改AccountModel.cs文件的UsersContext类以删除多元化选项(添加了OnModelCreating事件):

 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 – 将新字段添加到UserProfile

将所需的额外字段添加到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; } // <<<<<<<< EG THIS ADDED } 

5 – 在应用程序启动时迁移表格

现在,当应用程序启动时,您将设置数据库初始化策略,并使用read进行触发:

  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); } 

很明显,你需要添加各种使用语句来使这一切工作,但右键单击解决scheme将为你做。

补充笔记:

如果您决定(和我一样)为用户使用UserProfile以外的表,则需要更改多个条目以匹配。

  • 在您的SimpleMembershipInitializer类中,您需要引用新的表和列名称
  • 在帐户控制器和各种login和注册视图中,您需要引用新的模型字段(如果名称已更改)
  • UsersContext类中,您可以保持Userprofile类名不变,但需要更改Table属性以匹配表名。
  • UserProfile类中,您需要重命名字段以匹配新的表字段名称。
  • 在数据库中,您需要删除webpages_UsersInRolesUserProfile之间的关系,并在新的用户表和webpages_UsersInRoles之间添加关系,否则旧的参照完整性检查会在运行时中断您的工作。 (我强烈build议你删除现有的UserProfile表,并检查它是不是重新创build,如果是你有代码留下的东西)。

添加一个新的表到数据库,并称之为User_Details或类似的,创build一个用户,你可以检索用户的ID和强制到新表的细节。 这是一个简单的选项。

查看VS2012或VS2010附带的MVC4互联网项目模板。 在修改userprofile类的列之前,您需要确保数据库没有被创build。 您可以在POCO类中添加更多属性,然后重新生成数据库。 如果在生成数据库后添加属性,请确保使用EF迁移将这些新属性添加到数据库

当然,你可能知道你必须使你的RegisterModelUserProfile Model 。 我想要做的是在初始化数据库之前使用Migrations,并将以下内容放在Configuration.cs文件中:

  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 } 

然后我通过这三个易记的命令使用Packet Manager Console

  1. 启用的迁移
  2. 添加迁移迁移名称
  3. 更新数据库//将从Configuration.cs中播种

我同意TrueBlueAussie ,并会尽可能地说LazyInitialization不再是非常有用的东西,而且你不必再像以前那样称呼它了。 无论如何,你所要做的就是改变你在账户控制器中注册Action来调用这个方法:

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

注意:MVC5使用OWIN