我使用ASP.NET MVC-5
创建了一个新的Individual User Accounts
应用程序,然后更新了解决方案中的所有Nuget packages
。现在我试图遵循一些教程中显示的一些指导原则,但我遇到了一些问题。
第一个是在整个应用程序中使用的名为ApplicationRoleManager
的类未创建(ApplicationUserManager
已创建)。
第二个问题更多地是关于Entity-Framework
:我已经看到,为了使用用户和角色为数据库播种,许多人在ApplicationDbContext
类中创建了一个静态构造函数:
static ApplicationDbContext()
{
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
所以我添加了它,ApplicationDbInitializer
的实现是:
public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
{
protected override void Seed(ApplicationDbContext context)
{
InitializeIdentityForEF(context);
base.Seed(context);
}
//Create User=Admin@Admin.com with password=Admin@123456 in the Admin role
public static void InitializeIdentityForEF(ApplicationDbContext db)
{
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
const string name = "admin@admin.com";
const string password = "Admin@123456";
const string roleName = "Admin";
//Create Role Admin if it does not exist
var role = roleManager.FindByName(roleName);
if (role == null)
{
role = new IdentityRole(roleName);
var roleresult = roleManager.Create(role);
}
var user = userManager.FindByName(name);
if (user == null)
{
user = new ApplicationUser { UserName = name, Email = name };
var result = userManager.Create(user, password);
result = userManager.SetLockoutEnabled(user.Id, false);
}
// Add user admin to Role Admin if not already added
var rolesForUser = userManager.GetRoles(user.Id);
if (!rolesForUser.Contains(role.Name))
{
var result = userManager.AddToRole(user.Id, role.Name);
}
}
添加完所有内容后,我打开Package Manager Console
并输入Enable-Migrations
,然后Add-Migration someName
,然后Update-Database
。
结果是数据库已成功创建,但没有数据插入数据库
在注意到未插入数据后,我将Seed
逻辑移动到主控制器的Index方法,并在运行应用程序后插入数据。
我还需要将此行app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
添加到Startup.Auth.cs
文件中
所以我的问题是:
ApplicationRoleManager
课程
手动? seed
方法有效? 更新
我已将Seed
方法更改为:
protected override void Seed(ApplicationDbContext context)
{
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
//since there is no ApplicationRoleManager (why is that?) this is how i create it
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
const string name = "admin@admin.com";
const string password = "Admin@123456";
const string roleName = "Admin";
//Create Role Admin if it does not exist
var role = roleManager.FindByName(roleName);
if (role == null)
{
role = new IdentityRole(roleName);
var roleresult = roleManager.Create(role);
}
//app hangs here...
var user = userManager.FindByName(name);
if (user == null)
{
user = new ApplicationUser { UserName = name, Email = name };
var result = userManager.Create(user, password);
result = userManager.SetLockoutEnabled(user.Id, false);
}
// Add user admin to Role Admin if not already added
var rolesForUser = userManager.GetRoles(user.Id);
if (!rolesForUser.Contains(role.Name))
{
var result = userManager.AddToRole(user.Id, role.Name);
}
base.Seed(context);
}
现在,管理员角色已创建,但是当到达var user = userManager.FindByName(name);
时,应用程序会挂起,没有例外或任何消息......
答案 0 :(得分:6)
使用迁移时,您可以使用内置初始值设定项和Seed
方法:
Database.SetInitializer<ApplicationDbContext>(new
MigrateDatabaseToLatestVersion<ApplicationDbContext,
APPLICATION.Migrations.Configuration>());
并在APPLICATION.Migrations.Configuration
中(这是由Enable-Migrations
命令创建的):
protected override void Seed(ApplicationDbContext context)
{
// seed logic
}
作为角色管理员,您还可以使用RoleManager<ApplicationRole>
基础实施。
答案 1 :(得分:3)
在这种情况下,我对悬挂应用程序感到有些困惑。这个问题可以通过这种方式解决
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUserManager>(db));
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(db));
答案 2 :(得分:2)
对于任何使用带有Integer外键的ApplicationUser的人来说,代码是这样的:
var userManager = new ApplicationUserManager(new ApplicationUserStore(context));
var roleManager = new ApplicationRoleManager(new ApplicationRoleStore(context));
答案 3 :(得分:1)
这适用于默认的MVC 5项目。
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));
答案 4 :(得分:0)
发布的解决方案似乎并未解决userManager.FindByName(name)
调用中挂起的应用问题。我遇到了同样的问题。它几个小时前就在我当地工作了。我发布到Azure,它开始挂起。当我再次测试我的本地时,它突然开始挂在那一步。没有错误返回且没有超时(至少等待10-15分钟后)。 有没有人有任何提示来解决Yoav的终极问题?
我在添加角色之前运行了一些其他非常简单的种子进程,并且db.Foo.AddOrUpdate(foo)
调用正在运行而没有错误,但实际上没有将任何内容保存到数据库。
答案 5 :(得分:0)
我只是花了一个非常不愉快的半天来处理这件事。我终于设法让这个该死的东西开火了:
public static void InitializeIdentityForEF(ApplicationDbContext context)
{
context.Configuration.LazyLoadingEnabled = true;
//var userManager = HttpContext.Current
// .GetOwinContext().GetUserManager<ApplicationUserManager>();
//var roleManager = HttpContext.Current
// .GetOwinContext().Get<ApplicationRoleManager>();
var roleStore = new RoleStore<ApplicationRole, int, ApplicationUserRole>(context);
var roleManager = new RoleManager<ApplicationRole, int>(roleStore);
var userStore = new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context);
var userManager = new UserManager<ApplicationUser, int>(userStore);
...
这是极其漫长的一天的结束,我怀疑有人会告诉我为什么我不应该这样做。然而,我的Seed方法的其余部分使用非异步方法(FindByName / Create)进行了精美的激发。
答案 6 :(得分:0)
先生, 你的挣扎帮助我解决了这个问题,但我不得不做一点不同。
context.Configuration.LazyLoadingEnabled = true;
//var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
//var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
const string name = "admin@example.com";
const string password = "Admin@123456";
const string roleName = "Admin";
***var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));
var roleManager = new ApplicationRoleManager(new RoleStore<IdentityRole>(context));***
//Create Role Admin if it does not exist
var role = roleManager.FindByName(roleName);
if (role == null) {
role = new IdentityRole(roleName);
var roleresult = roleManager.Create(role);
}