【问题标题】:Updating user by UserManager.Update() in ASP.NET Identity 2通过 ASP.NET Identity 2 中的 UserManager.Update() 更新用户
【发布时间】:2017-01-25 11:34:57
【问题描述】:

我在MVC 5 项目中使用ASP.NET Identity 2,我想使用UserManager.Update() 方法更新Student 数据。但是,由于我继承自 ApplicationUser 类,我需要在调用更新方法之前将 Student 映射到 ApplicationUser。另一方面,当使用我也用于创建新学生的方法时,由于并发性而出现错误,因为我创建了一个新实例而不是更新。由于我厌倦了使用AutoMapper 解决问题,所以我需要一个稳定的修复程序来解决没有AutoMapper 的问题。你能澄清一下如何解决这个问题吗?我将StudentViewModel 传递给Controller 中的Update 方法,然后我需要将其映射到Student,然后将它们作为ApplicationUser 传递给UserManager.Update() 方法。另一方面,我想知道是否应该在 Controller 阶段检索并发送密码,而不是出于安全考虑将密码传递给 View?您能否也告诉我这个问题(在用户更新期间,我不更新密码,我必须将用户的密码保存在数据库中)。任何帮助将不胜感激。

实体类:

public class ApplicationUser : IdentityUser<int, ApplicationUserLogin,
                                     ApplicationUserRole, ApplicationUserClaim>, IUser<int>
{
    public string Name { get; set; }
    public string Surname { get; set; } 
    //code omitted for brevity
}

public class Student: ApplicationUser
{     
    public int? Number { get; set; }
}


控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Update([Bind(Exclude = null)] StudentViewModel model)
{
    if (ModelState.IsValid)
    {
        ApplicationUser user = UserManager.FindById(model.Id);

        user = new Student
        {
            Name = model.Name,
            Surname = model.Surname,
            UserName = model.UserName,
            Email = model.Email,
            PhoneNumber = model.PhoneNumber,
            Number = model.Number, //custom property
            PasswordHash = checkUser.PasswordHash
        };

        UserManager.Update(user);
    }
}

【问题讨论】:

  • 您是否使用自定义表学生并使用微软身份在学生表中插入数据??
  • 不,我只使用同一张表 (AspNetUsers),而我的 Student 实体继承自 ApplicationUser。有比答案更聪明的解决方案吗?
  • 其实我在这个场景中挣扎:stackoverflow.com/questions/39304464/…

标签: c# asp.net-mvc asp.net-identity automapper asp.net-identity-2


【解决方案1】:

这花了我一点时间来理解,但您只需要使用 UserManager。我的任务是简单地用新的日期更新 LoginViewModel。我尝试了不同的方法,但似乎唯一有效的是 FindByEmailAsync,这是我的 MODEL 特有的,因为我没有使用 Id 登录。

Case SignInStatus.Success
            Dim user As ApplicationUser = Await UserManager.FindByEmailAsync(model.Email)
            user.LastActivityDate = model.LastActivityDate

            UserManager.Update(user)

            Return RedirectToLocal(returnUrl)

【讨论】:

    【解决方案2】:

    我在 .netcore 1 上的回答

    这是我的工作,我希望可以帮助他们

    var user = await _userManager.FindByIdAsync(applicationUser.Id);
                        user.ChargeID = applicationUser.ChargeID;
                        user.CenterID = applicationUser.CenterID;
                        user.Name  = applicationUser.Name;
    var result = await _userManager.UpdateAsync(user);
    

    【讨论】:

      【解决方案3】:

      无需将student 作为ApplicationUser 传递给UserManager.Update() 方法(因为Student 类继承(因此ApplicationUser)。

      您的代码的问题在于您使用的是new Student 运算符,因此创建了一个新学生而不是更新现有学生。

      像这样更改代码:

      // Get the existing student from the db
      var user = (Student)UserManager.FindById(model.Id);
      
      // Update it with the values from the view model
      user.Name = model.Name;
      user.Surname = model.Surname;
      user.UserName = model.UserName;
      user.Email = model.Email;
      user.PhoneNumber = model.PhoneNumber;
      user.Number = model.Number; //custom property
      user.PasswordHash = checkUser.PasswordHash;
      
      // Apply the changes if any to the db
      UserManager.Update(user);
      

      【讨论】:

      • 亲爱的伊万,非常感谢您的帮助。实际上我已经尝试过与您提到的相同的方法,但在这种情况下,问题是:用户实例中没有 Number 属性。出于这个原因,我不得不将此实例转换为 Student(以便访问 Number 属性)。另一方面,是的,对于更新,创建一个新实例而不是使用当前实例是错误的。但是没有办法解决这个问题:(还有其他解决方案吗?我已经搜索了这个问题的解决方案几天但没有合适的解决方案:(((
      • 那么问题可能出在 UserManager 上。恐怕这超出了我的知识范围,也许其他人会帮助你,祝你好运(我已经尽力了,但由于我无法测试,我相信你它不起作用,所以我将在几分钟内删除答案)。
      • 不要删除答案。在您宝贵的帮助下,我解决了这个问题。只需在您的回答中将第一行更改为 var user = UserManager.FindById(model.Id) as Student; :) 非常感谢...
      • 能否请您更新您的答案,以便其他人也可以从中受益?
      猜你喜欢
      • 2014-05-15
      • 2015-03-08
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 2018-07-14
      • 2015-03-19
      相关资源
      最近更新 更多