4

I am struggling a bit with Asp.net Identity and updating a user. When I run the code below succeed is false and the error message is that the user with username exists. Which is - of course - obvious because you are updating a user, not creating a new one.

I have tried to remove the username without much success, I was then told that the Name (I believe it meant Username) could not be empty. Snip of code below.

public async Task<ActionResult> Edit(RegisterViewModel model) { var user = new User() { UserName = model.UserName, FirstName = model.FirstName, LastName = model.LastName, Email = model.EmailAddress, ApplicationId = Utilities.ApplicationUtilities.GetApplicationId() }; var userContext = new ApplicationDbContext(); var userStore = new UserStore<User>(userContext); var userManager = new UserManager<User>(userStore); var result = await userManager.UpdateAsync(user); if (result.Succeeded) { var selectedRole = model.SelectedRole; if (!userManager.IsInRole(user.Id, selectedRole.Id)) { // We are removing the user from the old role. He / she cannot have two or more roles userManager.RemoveFromRole(user.Id, model.OldRole); // Now we are adding the user to the new role userManager.AddToRole(user.Id, selectedRole.Id); userManager.Update(user); } userContext.SaveChanges(); // await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "UserManager"); } 

The solution based on the input from Jonesy became something like this:

/* * Some more information /Just in case someone else does the same * mistakes I did... */ model.OldRole = "User"; // Name of old role - not ID of old role model.SelectedRoleId = "Administrator"; // Name of new role, not ID of new role // This test is here just to check if the model is valid or not // By adding this part, you can check what is possibly wrong with your model if (!ModelState.IsValid) { var errors = ModelState .Where(x => x.Value.Errors.Count > 0) .Select(x => new {x.Key, x.Value.Errors}) .ToArray(); } // Creating the ApplicationDbContext object var userContext = new ApplicationDbContext(); // Getting the list of users (I tried using Find here, but got errors) var userList = userContext.Users.ToList(); // Decided to use First or Default. You also have to use double // equal-characters(=) otherwise you will get errors var user = userList.FirstOrDefault(u => u.UserName == model.UserName); // Checking that we really found the user to update if (user != null) { // populate the user object user.UserId = model.UserId; user.FirstName = model.FirstName; user.LastName = model.LastName; user.Email = model.EmailAddress; } // creating the UserStore object var userStore = new UserStore<User>(userContext); // ... and the userManager object var userManager = new UserManager<User>(userStore); // Do the update - I believe this is on the userManager-object // and not in the database var result = await userManager.UpdateAsync(user); // If we get an error, we return to list of Users // (You should log the error and also return the user to the form) if (!result.Succeeded) return RedirectToAction("Index", "UserManager"); // Do the actual update in the database userContext.SaveChanges(); // If the old role and the selected role is the same, we don't // have to update if (model.OldRole == model.SelectedRoleId) return RedirectToAction("Index", "UserManager"); // Get the selected role (sort of not needed, but here for clarity) string selectedRole = model.SelectedRoleId; // We are removing the user from the old role. // In our application a user cannot have two or more roles userManager.RemoveFromRole<User, string>(user.UserId, model.OldRole); // Now we are adding the user to the new role userManager.AddToRole<User, string>(user.UserId, selectedRole); // We are updating the userManager-object userManager.Update(user); // And storing the information in the database userContext.SaveChanges(); // Returning the user to the list of users return RedirectToAction("Index", "UserManager"); 
1
  • With many users you will run into performance problems. Don't do a ToList() before FirstOrDefault(), thats a completely waste of resources both on you server and database. You will get all users into memory and then do the filtering. If you do it like this: userContext.Users.FirstOrDefault(u => u.UserName == model.UserName); your database will do the filtering for you. Commented Oct 20, 2015 at 12:47

2 Answers 2

6

use your dbContext to pull the user to update, instead of creating a new one:

var user = userContext.Find(model.UserName); 

or you may need

var user = userContext.FirstOrDefault(u => u.UserName = model.UserName && u.Email = model.EmailAddress); if(user != null) { //update user } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for pointing me in the right direction Jonesy. You were right. I was creating a new object instead of finding the one I was to update.
4

this is an old one but just wanted to post my solution to the same update issue

var user = UserManager.FindByEmail(model.Email); user.Address = model.Address; user.City = model.City; user.State = model.State; var result = await UserManager.UpdateAsync(user); 

you can also manage roles

user.Roles.Add(Role); user.Roles.Remove(Role); 

1 Comment

avar user = UserManager.FindById(User.Identity.GetUserId()); can be used instead of FindMyEmail

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.