如何在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的回答,对他们充分的信任。 它修改了现有的UserProfile
和UserContext
类,因为它们直接与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_UsersInRoles
和UserProfile
之间的关系,并在新的用户表和webpages_UsersInRoles
之间添加关系,否则旧的参照完整性检查会在运行时中断您的工作。 (我强烈build议你删除现有的UserProfile
表,并检查它是不是重新创build,如果是你有代码留下的东西)。
添加一个新的表到数据库,并称之为User_Details或类似的,创build一个用户,你可以检索用户的ID和强制到新表的细节。 这是一个简单的选项。
查看VS2012或VS2010附带的MVC4互联网项目模板。 在修改userprofile类的列之前,您需要确保数据库没有被创build。 您可以在POCO类中添加更多属性,然后重新生成数据库。 如果在生成数据库后添加属性,请确保使用EF迁移将这些新属性添加到数据库
当然,你可能知道你必须使你的RegisterModel
和UserProfile 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
:
- 启用的迁移
- 添加迁移迁移名称
- 更新数据库//将从Configuration.cs中播种
我同意TrueBlueAussie ,并会尽可能地说LazyInitialization不再是非常有用的东西,而且你不必再像以前那样称呼它了。 无论如何,你所要做的就是改变你在账户控制器中注册Action来调用这个方法:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, propertyValues: new { model.Email, model.ImageUrl, model.DateJoined });
注意:MVC5使用OWIN