2014-05-12 68 views
3

我在使用Asp.net Identity和更新用户方面挣扎了一番。当我运行下面的代码成功是错误的,错误消息是用户名存在。当然,这是显而易见的,因为您正在更新用户,而不是创建新用户。使用Asp.Net身份更新用户身份 - 存在用户名

我试图删除用户名没有太大的成功,我被告知名称(我相信它意味着用户名)不能为空。 下面的代码片段。

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

基于从Jonesy输入溶液变成是这样的:

/* 
* 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"); 
+0

拥有众多用户,你会遇到性能问题。不要在FirstOrDefault()之前做一个ToList(),这就完全浪费了你的服务器和数据库的资源。你会让所有用户进入内存,然后进行过滤。如果你这样做:userContext.Users.FirstOrDefault(u => u.UserName == model.UserName);你的数据库会为你做过滤。 – Howie

回答

5

用你的DbContext拉用户更新,而不是创建一个新问题:

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

或者您可能需要

var user = userContext.FirstOrDefault(u => u.UserName = model.UserName && u.Email = model.EmailAddress); 

if(user != null) 
{ 
    //update user 
} 
+0

谢谢你指点我在正确的方向琼斯。你是对的。我正在创建一个新对象,而不是找到我要更新的对象。 – Trond

2

这是一个古老的,但只是想后我的解决方案,以相同的更新问题

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

还可以管理角色

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

avar user = UserManager.FindById(User.Identity.GetUserId());可以用来代替FindMyEmail – Grayson