我们的应用程序中有一个屏幕,允许管理员角色的成员编辑用户帐户详细信息。
最终,任何用户对象都将发送到服务器并使用以下命令进行更新:
await userManager.UpdateAsync(user);
这正在按预期工作以更新用户记录。我们可以进行持久化到数据库的更改,例如用户名,电话号码等。
我看到的问题是,有时更新角色而不是向用户添加其他角色会删除所有角色。
在我们的ApplicationUser
对象上,我们具有这样的属性:
public virtual ICollection<IdentityUserRole<string>> Roles { get; set; } = new List<IdentityUserRole<string>>();
因此,我们可以在客户端和服务器之间反弹角色,作为用户对象的一部分。
我正在努力了解的是我看到的userManager.UpdateAsync(user);
方法的不一致行为。它显然可以正常工作,或者永远无法向用户添加任何角色。
每次提交对象时,正确地使用角色填充到达服务器的对象。基本流程是:
如何防止其删除角色?
谢谢!
更新
如@amirani的答案中所述,我尝试过滤现有列表。我已经设置AutoMapper
来完全忽略该属性。
.ForMember(x => x.Roles, opt => opt.Ignore());
现在我只是像这样过滤(仅此刻添加):
foreach (var userDtoRole in userDto.Roles)
{
if (user.Roles.FirstOrDefault(x => x.RoleId == userDtoRole) == null)
{
user.Roles.Add(new IdentityUserRole<string> {RoleId = userDtoRole, UserId = user.Id });
}
}
其他角色永远不会添加到基础数据库中。在执行UpdateUser
方法之前,我已经确认要更新的用户对象具有正确的角色列表。
答案 0 :(得分:1)
致电await userManager.UpdateAsync(user);
时,您正在使用其所有相关数据更新用户模型。您需要将新角色添加到现有角色列表中,而不是创建新的空列表并添加新记录。
答案 1 :(得分:1)
在下面尝试添加新角色的代码
private readonly ApplicationDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public HomeController(ApplicationDbContext context
, UserManager<ApplicationUser> userManager
, RoleManager<IdentityRole> roleManager)
{
_context = context;
_userManager = userManager;
_roleManager = roleManager;
}
public async Task<IActionResult> CreateUserAndRole()
{
await _userManager.CreateAsync(new ApplicationUser { UserName = "test@outlook.com", Email = "test@outlook.com" });
await _roleManager.CreateAsync(new IdentityRole { Name = "Admin" });
await _roleManager.CreateAsync(new IdentityRole { Name = "Administrator" });
return Ok();
}
public async Task<IActionResult> AddAdminRoleToUser()
{
ApplicationUser user = _context.Users.FirstOrDefault(u => u.UserName == "test@outlook.com");
var role = await _roleManager.FindByNameAsync("Admin");
user.Roles.Add(new IdentityUserRole<string> { RoleId = role.Id, UserId = user.Id });
await _userManager.UpdateAsync(user);
return Ok();
}
public async Task<IActionResult> AddAdministratorRoleToUser()
{
ApplicationUser user = _context.Users.FirstOrDefault(u => u.UserName == "test@outlook.com");
var role = await _roleManager.FindByNameAsync("Administrator");
user.Roles.Add(new IdentityUserRole<string> { RoleId = role.Id, UserId = user.Id });
await _userManager.UpdateAsync(user);
return Ok();
}