I created a new ASP.NET MVC-5
application with Individual User Accounts
and then updated all the Nuget packages
in the solution. Now I'm trying to follow some of the guidelines shown in some tutorials but I encountered some problems.
The first one is that a class called ApplicationRoleManager
which is being used throughout the application wasn't created (the ApplicationUserManager
was created).
The second problem is more about Entity-Framework
: I've seen that for seeding the database with a user and role many people create a static constructor in the ApplicationDbContext
class:
static ApplicationDbContext()
{
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
So I added it, and the implementation of the ApplicationDbInitializer
is:
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);
}
}
After adding everything I opened the Package Manager Console
and typed Enable-Migrations
, then Add-Migration someName
and then Update-Database
.
the results were that the database was created successfully but no data was inserted to the database.
After noticing the data wasn't inserted I moved the Seed
logic to the Index method of the home controller and the data was inserted after running the application.
I also needed to add this line: app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
to the Startup.Auth.cs
file.
So my questions are:
- Do I really need to enter the
ApplicationRoleManager
class manually? - How do I make the
seed
method work?
UPDATE
I've changed the Seed
method to:
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);
}
So now, the Admin role is created but when getting to var user = userManager.FindByName(name);
the application hangs with no exception or any message...
I just spent a deeply unpleasant half day dealing with this. I finally managed to get the damn thing to fire:
It's the end of an extremely long day, and I suspect someone's going to tell me why I shouldn't do this. The rest of my Seed method fires beautifully, however, using non-async methods (FindByName/Create).
And for anyone using the ApplicationUser with Integer foreign key, the code is this one:
It doesn't appear that the solutions posted address the issue of the app hanging on the call of
userManager.FindByName(name)
. I'm running into the same problem. It worked a few hours ago on my local. I published to Azure and it started hanging. When I tested my local again it all of a sudden started hanging at that step. No error is returned and no timeout (at least after waiting 10-15 minutes). Does anyone have any tips to address Yoav's ultimate question?I have some other very simple seeding processes that run before adding roles, and
db.Foo.AddOrUpdate(foo)
calls are running without error, but not actually saving anything to the database.Sir goobering, You struggles have helped me get passed this problem, I had to do it a little different though.
I also was a bit confused about hanging of application in this case. The problem can be solved in this way
This works great for default MVC 5 project.