我正在处理的应用程序涉及能够将用户添加到各种角色。现在,我能够创建用户和角色,以及查看用户在种子数据中分配的角色。但是,当我尝试通过应用程序本身将用户添加到角色时,更改实际上不会保存回数据库。我没有收到任何类型的错误页面。以下是我认为相关的代码。
我的AccountController中的UserRole方法:
[Authorize(Roles = "Admin")]
public ActionResult UserRoles(string id)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == id);
var model = new SelectUserRolesViewModel(user);
return View(model);
}
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult UserRoles(SelectUserRolesViewModel model)
{
if (ModelState.IsValid)
{
var idManager = new IdentityManager();
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == model.UserName);
idManager.ClearUserRoles(user.Id);
foreach (var role in model.Roles)
{
if (role.Selected)
{
idManager.AddUserToRole(user.Id, role.RoleName);
}
}
return RedirectToAction("IndexUser");
}
return View();
}
Identity Manager类:
public class IdentityManager
{
public bool AddUserToRole(string userId, string roleName)
{
var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var idResult = um.AddToRole(userId, roleName);
return idResult.Succeeded;
}
public void ClearUserRoles(string userId)
{
var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var user = um.FindById(userId);
var currentRoles = new List<IdentityUserRole>();
currentRoles.AddRange(user.Roles);
foreach (var role in currentRoles)
{
um.RemoveFromRole(userId, role.RoleId);
}
}
}
模型类:
public class SelectUserRolesViewModel
{
// Enable initialization with an instance of ApplicationUser:
public SelectUserRolesViewModel(ApplicationUser user)
: this()
{
this.UserName = user.UserName;
var Db = new ApplicationDbContext();
// Add all available roles to the list of EditorViewModels:
var allRoles = Db.Roles;
foreach (var role in allRoles)
{
var rvm = new SelectRoleEditorViewModel(role);
this.Roles.Add(rvm);
}
// Set the Selected property to true for those roles for
// which the current user is a member:
foreach (var userRole in user.Roles)
{
var checkUserRole = this.Roles.Find(r => r.RoleID == userRole.RoleId);
checkUserRole.Selected = true;
}
}
public string UserName { get; set; }
public List<SelectRoleEditorViewModel> Roles { get; set; }
}
// Used to display a single role with a checkbox, within a list structure:
public class SelectRoleEditorViewModel
{
public SelectRoleEditorViewModel() { }
public SelectRoleEditorViewModel(IdentityRole role)
{
this.RoleName = role.Name;
this.RoleID = role.Id;
}
public bool Selected { get; set; }
[Required]
public string RoleName { get; set; }
[Required]
public string RoleID { get; set; }
}
现在我知道AddUserToRole方法可以正常工作,因为我在种子数据库时直接调用它并且它可以工作。有人有什么想法吗?
如需完整披露,此代码取自以下教程: http://www.codeproject.com/Articles/682113/Extending-Identity-Accounts-and-Implementing-Rol
修改 关于网页实际发生的更多描述。当我导航到页面以将角色分配给所选用户时,它会列出所有角色并预先检查用户已分配给的所有角色。我可以进行一些更改,然后单击“保存”按钮。但是,此时它返回相同的视图,但没有任何用户角色信息。然后,我可以再次单击“保存”,然后返回到用户列表页面。所以我猜想发生的事情是当第一次提交页面时,附加了模型值(用户和角色)模型状态总是无效,因此它绕过UserRoles方法中的所有代码并直接转向错误处理返回View()行的结尾。但是,我不知道为什么模型会无效。用户无处输入可能违反某种数据库或网页验证的值。每个角色旁边都有一个复选框,用于表示用户将分配给哪些角色。
答案 0 :(得分:1)
您没有将更改保存到数据库中 使用Db.SaveChanges();保存更改
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult UserRoles(SelectUserRolesViewModel model)
{
if (ModelState.IsValid)
{
var idManager = new IdentityManager();
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == model.UserName);
idManager.ClearUserRoles(user.Id);
foreach (var role in model.Roles)
{
if (role.Selected)
{
idManager.AddUserToRole(user.Id, role.RoleName);
}
}
Db.SaveChanges(); //for saving changes to the database
return RedirectToAction("IndexUser");
}
return View();
}
希望它对您有帮助,请勾选答案。 :)
答案 1 :(得分:1)
我希望这可以帮助遇到这个并需要答案的人。您遇到的问题是您的model.roles返回null,因此当您尝试添加新用户时,它应该会出错。但是,如果您检查它不是空的,那么它不会给出任何错误。此外,下次尝试自己添加错误消息时,如果无法执行操作,请使用try catch,您会收到错误消息。请尝试以下
if (model.Roles == null)
{
model.Roles = new Role();
}
else {
foreach (var role in model.Roles)
{
if (role.Selected)
{
idManager.AddUserToRole(user.Id, role.RoleName);
}
}
}
答案 2 :(得分:0)
在代码中实例化了3个DbContexts,看起来它们可能是嵌套的,这可能会有问题。尝试更改IdentityManager
以使用外部DbContext ...
public class IdentityManager
{
private ApplicationDbContext context;
public IdentityManager ()
{
context = new ApplicationDbContext(); // if none supplied
}
public IdentityManager (ApplicationDbContext applicationDbContext)
{
context = applicationDbContext;
}
public bool AddUserToRole(string userId, string roleName)
{
var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var idResult = um.AddToRole(userId, roleName);
return idResult.Succeeded;
}
public void ClearUserRoles(string userId)
{
var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var user = um.FindById(userId);
var currentRoles = new List<IdentityUserRole>();
currentRoles.AddRange(user.Roles);
foreach (var role in currentRoles)
{
um.RemoveFromRole(userId, role.RoleId);
}
}
}
并更改调用代码以传入DbContext ...
var Db = new ApplicationDbContext();
var idManager = new IdentityManager(Db);
var user = Db.Users.First(u => u.UserName == model.UserName);
idManager.ClearUserRoles(user.Id);
foreach (var role in model.Roles)
{
if (role.Selected)
{
idManager.AddUserToRole(user.Id, role.RoleName);
}
}
答案 3 :(得分:0)
在ClearUserRoles函数中,您有um.RemoveFromRole(userId, role.RoleId);
。您将RoleId放在应该是RoleName的位置。