Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Identity UserManager UpdateAsync Removing Roles

There is a screen in our application that allows members of the Administrators role to edit user account details.

Ultimately any user object is sent to the server and updated using:

await userManager.UpdateAsync(user);

This is working as expected for updating user records. We can make changes that are persisted to the database such as usernames, phone numbers etc.

The issue I'm seeing is that when updating the Roles sometimes rather than adding an additional role to the user it removes all the roles.

On our ApplicationUser object we have a property like this:

public virtual ICollection<IdentityUserRole<string>> Roles { get; set; } = new List<IdentityUserRole<string>>();

So we can bounce roles between client and server as part of a user object.

What I'm struggling to understand is the inconsistent behavior of the userManager.UpdateAsync(user); method I'm seeing. It clearly works or it would never be capable of adding any role to a user.

The object arriving at the server is correctly populated with the roles each time it is submitted. The basic flow is:

  1. Add role and submit
  2. The role is added to the user correctly
  3. Add additional role and submit
  4. All Roles are removed

How can I prevent it from removing roles?

Thanks!

UPDATE

As detailed in the answer from @amirani I've tried filtering the existing list instead. I've setup AutoMapper to ignore the property entirely.

.ForMember(x => x.Roles, opt => opt.Ignore());

And am now just filtering like this (only adding at the moment):

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

The additional roles are never added to the underlying database. I've confirmed that the user object being updated has the correct list of roles prior to executing the UpdateUser method.

like image 261
Jammer Avatar asked Aug 15 '18 11:08

Jammer


1 Answers

When you call await userManager.UpdateAsync(user);You are updating user model with all its related data. You need to add new role to an existing roles list instead of creating new empty list and adding new record.

like image 84
amirani Avatar answered Oct 18 '22 23:10

amirani