了解MVC-5身份

时间:2014-08-04 14:23:44

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 asp.net-identity-2

我使用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文件中 所以我的问题是:

  1. 我真的需要进入ApplicationRoleManager课程 手动?
  2. 如何使seed方法有效?
  3. 更新
    我已将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);时,应用程序会挂起,没有例外或任何消息......

7 个答案:

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