在我的项目中,我使用 WebSecurity 和 EF 代码优先迁移。
我有我的自定义 UserProfile 类,我想将其与 WebSecurity 结合。
我想在 Seed 方法的迁移配置类中为用户播种。
所以我试试这个:
#1)
if (!Roles.RoleExists("admin"))
Roles.CreateRole("admin");
if (!WebSecurity.UserExists(AdminUserName))
WebSecurity.CreateUserAndAccount(
AdminUserName,
"admin",
new {Email = "admin@mindmap.pl"});
但它提示我应该先调用 WebSecurity.InitializeDatabaseConnection。
好的,这是有道理的。所以我将以下行添加到我的 Global.asax 中:
#2)
WebSecurity.InitializeDatabaseConnection(
_connectionStringName,
"UserProfiles",
"Id",
"UserName",
autoCreateTables: true);
但比下面几行:
#3)
var dbMigrator = new DbMigrator(_configuration);
dbMigrator.Update();
抛出错误:
There is already an object named 'UserProfiles' in the database.
好吧,这再次有意义,因为迁移会尝试创建刚刚由 WebSecurity 创建的表。
我找到了一个解决方法:我将#2) 放在#1) 的正上方。比它奏效。
- 迁移创建了 UserProfiles 表
- WebSecurity 附加到现有的 UserProfiles 表并创建它需要的其他表
- Seeds 在找到所需的表并初始化 WebSecurity 后开始工作。
问题是我必须在 seed 方法中初始化 WebSecurity,这有点臭。
我的问题是如何将 WebSecurity.InitializeDatabaseConnection 移回 Global.asax?
请您参考如下方法:
您可以在 Global.asax 中编写此代码:
if (!WebMatrix.WebData.WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection(_connectionStringName, "UserProfile", "UserId", "UserName", autoCreateTables: true);
然后通过这种方式使用迁移进行播种,您可以在此处放置自定义字段,例如电子邮件,...:
private void SeedMemberShip()
{
if (!WebMatrix.WebData.WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection(_connectionStringName, "UserProfile", "UserId", "UserName", autoCreateTables: true);
var roles = (SimpleRoleProvider)Roles.Provider;
var membership = (SimpleMembershipProvider)Membership.Provider;
if (!roles.RoleExists("Admin"))
{
roles.CreateRole("Admin");
}
if (membership.GetUser(username, false) == null)
{
membership.CreateUserAndAccount(username, password);
}
if (!roles.GetRolesForUser(username).Contains("Admin"))
{
roles.AddUsersToRoles(new[] { username }, new[] { "Admin" });
}
}
然后调用上面的方法就是seed方法:
protected override void Seed(YourContext context)
{
SeedMemberShip();
}
