繁体   English   中英

MVC5:UserManager.AddToRole():“将用户添加到角色时出错:找不到UserId”?

[英]MVC5: UserManager.AddToRole(): “Error Adding User to Role: UserId not found”?

我一直在尝试使用MVC5 / EF6并尝试使用Code-First Migrations进行新的身份验证。 解决方案中的所有内容当前正在构建,我可以添加Migration ,但是当我通过VS2013中的package manager console执行update-database ,我的Configuration.cs文件无法将我的测试数据完全处理到我的表中并输出Error Adding User to Role: UserId not found

我已经尝试显式设置用户ID并让它由Manager生成(如某些示例所示),但每次收到相同的错误消息。 我知道我的Configuration.cs文件的#region User & User Roles中的错误是失败的,但我不确定原因:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using PersonalPortfolio2.Helper;
using PersonalPortfolio2.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Diagnostics;
using System.Linq;

namespace PersonalPortfolio2.Models
{
    public sealed class Configuration : DbMigrationsConfiguration<PersonalPortfolio2.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(PersonalPortfolio2.Models.ApplicationDbContext context)
        {
            BlobHelper bh = new BlobHelper();
            //LocationHelper lh = new LocationHelper();
            ApplicationDbContext db = new ApplicationDbContext();

            #region Roles
            try
            {
                List<string> myRoles = new List<string>(new string[] { "Root", "Admin", "Outsider", "Client", "Primary" });
                var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

                foreach (string r in myRoles)
                {
                    RoleManager.Create(new IdentityRole(r));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error Create Roles: " + ex.Message);
            }
            #endregion

            #region User & User Roles
            var store = new UserStore<ApplicationUser>(context);
            var manager = new UserManager<ApplicationUser>(store);

            List<ApplicationUser> myUsers = GetTestUsers();
            var passwordHasher = new PasswordHasher();

            foreach (var u in myUsers)
            {
                var userExists = db.Users.Where(a => a.Email == u.Email).FirstOrDefault();
                if (userExists == null)
                {
                    var user = new ApplicationUser
                    {
                        Email = u.Email,
                        PasswordHash = passwordHasher.HashPassword("P@ssword1"),
                        LockoutEnabled = false,
                        Name = u.Name,
                        Position = u.Position,
                        RegisteredDate = DateTime.Now,
                        LastVisitDate = DateTime.Now,
                        OrganizationId = u.OrganizationId,
                        ProfilePictureSrc = u.ProfilePictureSrc,
                    };

                    try
                    {
                        var userCreateResult = manager.Create(user);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error Add User: " + ex.Message + "\n" + ex.InnerException);
                    }

                    // Add User to Roles
                    List<string> usersRoles = GetUserRoles(u.Email);
                    bool codeHit = false;
                    foreach (string role in usersRoles)
                    {
                        try
                        {
                            codeHit = true;
                            manager.AddToRole(user.Id, role);
                        }
                        catch (Exception ex)
                        {
                            // ERROR!
                            throw new Exception("Error Adding User to Role: " + ex.Message + "\n" + ex.Data + "\n" + ex.InnerException + "\nName: " + user.Name + "\nEmail: " + user.Email + "\nuser.ID: " + user.Id + "\nu.Id: " + u.Id + "\nRole: " + role + "\nCodeHit: " + codeHit);
                        }
                    }
                }

            }
            #endregion

}

            #region Helpers
            private List<ApplicationUser> GetTestUsers()
            {
                List<ApplicationUser> testUsers = new List<ApplicationUser>
                {
                    new ApplicationUser
                    {
                        Id = "1",
                        Email = "Admin@abc.com",
                        Name = "Admin User",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Site Administrator",
                        PhoneNumber = "1234564321",
                    },
                    new ApplicationUser
                    {
                        Id = "2",
                        Email = "first.last@hotmail.com",
                        Name = "James Woods",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Software Developer / Web Designer",
                        PhoneNumber = "1234567890",
                    },
                    new ApplicationUser
                    {
                        Id = "3",
                        Email = "tyler.perry@gmail.com",
                        Name = "Tyler Perry",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Company Contact",
                        PhoneNumber = "1234567890",
                    }
                };
                return testUsers;
            }


            public List<string> GetUserRoles(string user)
            {
                List<string> myRoles = new List<string>();
                switch (user)
                {
                        //"Root", "Admin", "Outsider", "Client", "Primary"
                    case "Admin@abc.com":
                        myRoles = new List<string>(new string[] { "Root", "Admin" });
                        break;
                    case "first.last@hotmail.com":
                        myRoles = new List<string>(new string[] { "Admin" });
                        break;
                    case "tyler.perry@gmail.com":
                        myRoles = new List<string>(new string[] { "Client", "Outsider" });
                        break;
                    default:
                        myRoles = new List<string>(new string[] {"[user] not found."});
                        break;
                }
                return myRoles;
            }
            #endregion

    }
}

任何人都可以通过我可能忽略的内容提供一些见解吗? 有关完整的详细信息,我当前的catch语句输出如下:

Error Adding User to Role: UserId not found.
System.Collections.ListDictionaryInternal

Name: Admin User
Email: Admin@abc.com
user.ID: 1
u.Id: 1
Role: Root
CodeHit: True

当我注释掉显式Id = "1",对于我的管理员用户, user.IDu.Id变为: ab753316-3d7b-4f98-a13a-d19f7c926976 我曾经以为它可能是我的帮助方法GetTestUsers()GetUserRoles(u.Email)这是问题,但在我的try/catch和我正在使用的codeHit布尔变量之间,我已经验证了问题肯定来自manager.AddToRole(user.Id, role)

我将此留给这里可能有类似问题的人。 我有完全相同的“症状”。 事实证明,与存储的密码相关的问题不符合配置的密码策略(至少一个大写字符,一个小写字符等等)。

根据以下注释和答案,通常,当不遵循任何用户创建约束或策略时,将抛出相同的模糊错误消息。

这可能包括以下内容:

  • 未遵循密码政策(这似乎是最常见的原因)
  • 必填字段作为空字符串/ null传递
  • 用户名或电子邮件重复

实际上存在许多可能导致此错误发生的问题。 如果上述问题无法解决您的问题,我建议如下:

  1. 熟悉为您的解决方案设置的identityprovider的规则和策略
  2. 根据@Ted在下面的回答,在UserManager.Create方法上跟踪或设置断点以查看结果,因为这可能会揭示问题的原因。

CraftBeerHipsterDude的回答帮助我找到了同样情况的答案。 如果AddToRole失败,那么诀窍是查看从Usermanager.Create(...)返回的结果。 它可能不会抛出异常,但仍返回表示创建失败的结果。 在我的情况下,它是“用户名已存在”。

概括:检查早期操作的结果以追踪实际错误。

对问题创建者的回答:不应输入UserId,将其留给实体框架为用户创建它。您也尝试将其作为整数输入,但基于角色的安全性中的用户ID是GUID以字符串的形式,所以无论如何都不能尝试为期望字符串的列添加整数值。

现在这对我来说不是问题,但我遇到了同样错误的其他几个问题:

我试图弄清楚我错过了什么,但没有发现任何错误。

所以我使用VS的另一个实例作为种子代码的调试器(在另一个线程中找到它):

    if (System.Diagnostics.Debugger.IsAttached == false)
    System.Diagnostics.Debugger.Launch();

我注意到用户在添加到角色时确实有一个Id。 最后,我能够通过添加一个空的catch块来解决这个问题。代码由于错误的错误而没有抛出异常,并且用户被添加到正确的角色:

    try
    {
        var newUser = userManager.FindByEmail(superuserToInsert.Email);
        userManager.AddToRole(newUser.Id, "Super users");
    }
    catch 
    {
    }

在我尝试将新创建的用户添加到角色之前,种子似乎回滚了用户的创建,并且从未在用户数据库中创建用户。

但是当我完全删除添加到角色部分时,用户被添加到数据库中,并且在第二次运行时编辑了一些配置代码,用户可能被添加到角色中,这使我认为这是一个错误的错误抛出..用空catch块忽略这个错误错误似乎也忽略了用户创建的回滚(这必须发生在添加到角色部分之前的窗帘后面)导致用户在添加角色部分时存在码。

希望它可以帮助某人

编辑:

以上几乎解决了我所有的头痛,但我注意到仍然有大约300个帐户无法创建(但没有抛出错误)。 一个简单的FULL OUTER JOIN并使用源数据库表检查用户数据库,这使我认为在“UserName”和“Email”列的值中都带有短划线( - )字符的用户停止了用户的创建,这个是这样的。

这是一个简单的修复,只是将用户管理器配置为使用超过字母数字字符:(即使属性名称似乎只指向“用户名”,它也影响“电子邮件”)

    var userManager = new UserManager<ApplicationUser>(userStore);

    userManager.UserValidator = new UserValidator<ApplicationUser(userManager)
    {
        AllowOnlyAlphanumericUserNames = false,
    }; 

// Miske

我会避免在Seed方法中使用UserManagerRoleManager 相反,我只会使用上下文。 我使用的是以下创建用户并将其分配给角色的内容:

protected override void Seed(DbModelContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException("context", "Context must not be null.");
    }

    const string UserName = "User";
    const string RoleName = "UserRole";

    var userRole = new IdentityRole { Name = RoleName, Id = Guid.NewGuid().ToString() };
    context.Roles.Add(userRole);

    var hasher = new PasswordHasher();

    var user = new IdentityUser
                   {
                       UserName = UserName,
                       PasswordHash = hasher.HashPassword(UserName),
                       Email = "test@test.com",
                       EmailConfirmed = true,
                       SecurityStamp = Guid.NewGuid().ToString()
                   };

    user.Roles.Add(new IdentityUserRole { RoleId = userRole.Id, UserId = user.Id });

    context.Users.Add(user);

    base.Seed(context);
}

Entity类是自定义实现(因为我想使用GUID作为ID),但它们派生自框架类。 如果将它们更改为适当的框架类,它应该以相同的方式工作。

编辑

我删除了自定义类并将它们切换到框架类,因为有一些混乱。

这节省了我的第二天。 谢谢@Daffy朋克。 就我而言,问题是密码。 以前是“abc”。

var studentPassword = "abcABC_9";
                        var user = new ApplicationUser { UserName = "abc", Email = 1@gmail.com };
                        var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
                        var result = await UserManager.CreateAsync(user, studentPassword.ToString());
                        await UserManager.AddToRoleAsync(user.Id, "Student");

在我的情况下的问题是我使用(用户名)用户而不是Id,工作代码如下:

 public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Username, Email = model.Username, workshopId =model.workshopId};
                var rolesList = _context.Roles.ToList();
                string role = rolesList.FirstOrDefault(r => r.Id == model.SelectedRoleId).Name;
                var result = await UserManager.CreateAsync(user, model.Password);

                // Add User to the selected role from the list in .cshtml
                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                    result =await UserManager.AddToRoleAsync(user.Id, role);
                    // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                    // Send an email with this link
                    // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                    // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                    // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

                    return RedirectToAction("Index", "Home");
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM