Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a user with Asp.Net Identity - username exists

Tags:

c#

asp.net

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");
like image 964
Trond Avatar asked Jan 10 '23 14:01

Trond


1 Answers

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
}
like image 76
Jonesopolis Avatar answered Jan 13 '23 02:01

Jonesopolis