【问题标题】:Understanding MVC-5 Identity了解 MVC-5 身份
【发布时间】:2014-09-27 01:26:52
【问题描述】:

我使用Individual User Accounts 创建了一个新的ASP.NET MVC-5 应用程序,然后更新了解决方案中的所有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 方法起作用?

更新
我已将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); 时,应用程序挂起,没有任何异常或任何消息...

【问题讨论】:

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


    【解决方案1】:

    使用迁移时,您可以使用内置初始化程序和 Seed 方法:

    Database.SetInitializer<ApplicationDbContext>(new 
        MigrateDatabaseToLatestVersion<ApplicationDbContext, 
        APPLICATION.Migrations.Configuration>());
    

    APPLICATION.Migrations.Configuration 中(这是由Enable-Migrations 命令创建的):

    protected override void Seed(ApplicationDbContext context)
    {
        // seed logic
    }
    

    作为角色管理器,您还可以使用RoleManager&lt;ApplicationRole&gt; 基本实现。

    【讨论】:

    • 不能使用自定义初始化器吗?
    • 当然你可以 - 只是扩展MigrateDatabaseToLatestVersion 而不是DropCreateDatabaseIfModelChanges,但是你正在做的事情不应该放在那里。看看IdenitityConfig.csAuthConfig.cs/Startup.Auth.cs...
    • 能否解释一下“BUT”后面的部分?
    • 如果您使用Individual User Accounts 设置创建了一个新的MVC 5 项目,您应该在~/App_Start/ 下为您创建这两个文件,包括用户/角色管理器的所有设置逻辑“in正确的地方”(不是必须在那里,而是“最佳实践”)......
    • 所以除了设置逻辑(我猜你的意思是ApplicationUserManagerCreate() 方法中的所有内容)之外,数据的播种也应该在那里进行?
    【解决方案2】:

    在这种情况下,我也对挂起应用程序感到有些困惑。问题可以这样解决

    var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUserManager>(db));
    var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(db));
    

    【讨论】:

    • 就是这样。我花了 4 个小时摆弄这个……讨厌这个 M$ 废话!
    【解决方案3】:

    对于任何使用带有整数外键的 ApplicationUser 的人,代码是这样的:

    var userManager = new ApplicationUserManager(new ApplicationUserStore(context));
    var roleManager = new ApplicationRoleManager(new ApplicationRoleStore(context));
    

    【讨论】:

    • 很高兴我能提供帮助,因为我在这个“简单”问题上浪费了很多时间。
    【解决方案4】:

    这非常适合默认的 MVC 5 项目。

    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));
    

    【讨论】:

      【解决方案5】:

      发布的解决方案似乎没有解决应用程序在调用userManager.FindByName(name) 时挂起的问题。我遇到了同样的问题。几个小时前它在我的本地工作。我发布到 Azure,它开始挂起。当我再次测试我的本地时,它突然开始挂在那一步。没有返回错误并且没有超时(至少在等待 10-15 分钟后)。 有没有人有任何提示可以解决 Yoav 的终极问题?

      我还有一些其他非常简单的播种过程在添加角色之前运行,db.Foo.AddOrUpdate(foo) 调用运行没有错误,但实际上没有将任何内容保存到数据库中。

      【讨论】:

        【解决方案6】:

        我刚刚度过了非常不愉快的半天来处理这个问题。我终于设法让这该死的东西开火了:

        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)很好地触发。

        【讨论】:

          【解决方案7】:

          古伯林先生, 你的努力帮助我解决了这个问题,但我不得不做一些不同的事情。

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

          【讨论】:

            猜你喜欢
            • 2015-07-02
            • 2014-04-30
            • 2014-10-12
            • 2013-09-06
            • 2014-09-10
            • 1970-01-01
            • 1970-01-01
            • 2019-07-08
            • 2014-03-03
            相关资源
            最近更新 更多