Microsoft.AspNetCore.Identity 和 EF Core,在测试旧密码时重置用户密码

Posted

技术标签:

【中文标题】Microsoft.AspNetCore.Identity 和 EF Core,在测试旧密码时重置用户密码【英文标题】:Microsoft.AspNetCore.Identity and EF Core, Reset User Password while testing old password 【发布时间】:2021-12-22 05:10:59 【问题描述】:

尝试使用 UserManager ChangePasswordAsync 进行密码重置

     public async Task<ActionResult> ChangePasswordAsync(ChangePwdInfo info)
     
        var result = await _userManager.ChangePasswordAsync(CurrentUser, info.PasswordCurrent, info.Password);
        if (result.Succeeded)
        
            LogInformation("Password changed successfully");
            return Ok();
        
        var err = result.Errors.FirstOrDefault();
        if (err?.Code == "PasswordMismatch")
        
            return SystemInfo("Current Password was not correct", $"Change password called with incorrect current password");
        

        return SystemError($"Password change result: ", $"Change password failed result.Errors.FirstOrDefault()?.Description");
    

ChangePasswordAsync 出错:

无法跟踪实体类型“ApplicationUser”的实例,因为已经在跟踪另一个与 'Id' 键值相同的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

所以看起来 _userManager 正在跟踪 ApplicationUser 但我不想/不需要它。但是没有.AsNoTracking() 选项,那么在这种情况下如何告诉EF 并且不要跟踪?

我确实引用了 _userManager 使用的共享 dbContext,因此我尝试使用以下内容(在 CheckPasswordSignInAsync 之后)清除更改跟踪,但这没有任何区别。

dbContext.ChangeTracker.Clear();

【问题讨论】:

【参考方案1】:

事实证明,我在其他地方获得了当前登录用户,并且正在使用 .AsNoTracking() 因为我不需要跟踪它。

_currentUser = _userManager.Users.AsNoTracking().SingleOrDefault(u => u.UserName == userEmail);

但是当我从上面删除 .AsNoTracking() 时,密码重置工作正常。

但是,当然应该有办法告诉 _userManager.ChangePasswordAsync 不跟踪用户,或者我错过了什么?

【讨论】:

以上是关于Microsoft.AspNetCore.Identity 和 EF Core,在测试旧密码时重置用户密码的主要内容,如果未能解决你的问题,请参考以下文章