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

我一直在尝试使用MVC5 / EF6并尝试使用Code-First Migrations进行新的身份validation。 解决方案中的所有内容当前正在构建,我可以添加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 { 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 myRoles = new List(new string[] { "Root", "Admin", "Outsider", "Client", "Primary" }); var RoleManager = new RoleManager(new RoleStore(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(context); var manager = new UserManager(store); List 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 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 GetTestUsers() { List testUsers = new List { 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 GetUserRoles(string user) { List myRoles = new List(); switch (user) { //"Root", "Admin", "Outsider", "Client", "Primary" case "Admin@abc.com": myRoles = new List(new string[] { "Root", "Admin" }); break; case "first.last@hotmail.com": myRoles = new List(new string[] { "Admin" }); break; case "tyler.perry@gmail.com": myRoles = new List(new string[] { "Client", "Outsider" }); break; default: myRoles = new List(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布尔变量之间,我已经validation了问题肯定来自manager.AddToRole(user.Id, role)

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

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

这可能包括以下内容:

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

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

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

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

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

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

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

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

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

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

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

  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(userStore); userManager.UserValidator = new UserValidator 

// 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),但它们派生自框架类。 如果将它们更改为适当的框架类,它应该以相同的方式工作。

编辑

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