AspNetCore.Identity 重置密码 - 无法跟踪 'X' 的实例
AspNetCore.Identity Reset Password - Instance of 'X' cannot be tracked
我正在尝试使用 AspNetCore.Identity 程序集实现密码重置机制。首先是用户说他们忘记了密码,输入他们的电子邮件和密码,然后提交。最终调用此代码
IdentUser user = UserManager.FindByName(passwordObj.username);
//Some unrelated code in between
Task<string> codeTask = UserManager.GeneratePasswordResetTokenAsync(user);
string code = Base64ForUrlEncode(codeTask.Result);
string applicationUrl = string.Format("{0}/{1}?userId={2}&&token={3}", ApplicationUrl, "ResetPasswordView", user.Id, code);
我在生成重置密码令牌时没有任何问题,任务运行完成,我收到一封包含正确 URL 的电子邮件。
但是,当我尝试重置密码时,我遇到了这段代码
public JsonResult ResetPassword(ResetPasswordModel passwordObj)
{
IdentUser User = UserManager.FindById(passwordObj.userId);
//Unrelated code
Task<IdentityResult> resetPassTask = UserManager.ResetPasswordAsync(User, Base64ForUrlDecode(passwordObj.token), passwordObj.resetPassword);
IdentityResult user = resetPassTask.Result;
....
}
并且 resetPassTask.Result
行正在生成一个异常说“无法跟踪实体类型 'IdentUser' 的实例,因为已经有另一个具有相同键的这种类型的实例被跟踪。
我对 ASP.NET Core 还比较陌生,我才刚刚开始了解异步调用的来龙去脉,所以我很难调试它。我已经在 SO 上搜索了答案,但没有找到任何可以解决我的问题的东西,所以我来了。关于如何修复或调试此问题的任何想法?
所以,我找出了我的问题,并发布了我的修复程序,希望可以帮助面临此问题的其他人。
我的 FindById 函数是在 AspNetCore.Identity 的 UserManager IdentUserManager
的扩展中实现的。 FindById 不是异步的 ->
public IdentUser FindById(int userId)
{
return _dbContext.Users.Include(user => user.IdentUserProfile)
.Include(role => role.IdentUserProfile.IdentUserOrgRole)
.Include(client => client.IdentUserProfile.IdentMapApplicationsWithUser).FirstOrDefault(x => x.Id == userId);
}
因此,我现在使用 AspNetCore.Identity 的 FindByIdAsync
IdentUser User = await UserManager.FindByIdAsync(passwordObj.userId.ToString());
这解决了我的问题。不完全确定原因是什么,但是直接使用 DbContexts
和异步调用似乎不太协调。有任何解释欢迎评论
我正在尝试使用 AspNetCore.Identity 程序集实现密码重置机制。首先是用户说他们忘记了密码,输入他们的电子邮件和密码,然后提交。最终调用此代码
IdentUser user = UserManager.FindByName(passwordObj.username);
//Some unrelated code in between
Task<string> codeTask = UserManager.GeneratePasswordResetTokenAsync(user);
string code = Base64ForUrlEncode(codeTask.Result);
string applicationUrl = string.Format("{0}/{1}?userId={2}&&token={3}", ApplicationUrl, "ResetPasswordView", user.Id, code);
我在生成重置密码令牌时没有任何问题,任务运行完成,我收到一封包含正确 URL 的电子邮件。
但是,当我尝试重置密码时,我遇到了这段代码
public JsonResult ResetPassword(ResetPasswordModel passwordObj)
{
IdentUser User = UserManager.FindById(passwordObj.userId);
//Unrelated code
Task<IdentityResult> resetPassTask = UserManager.ResetPasswordAsync(User, Base64ForUrlDecode(passwordObj.token), passwordObj.resetPassword);
IdentityResult user = resetPassTask.Result;
....
}
并且 resetPassTask.Result
行正在生成一个异常说“无法跟踪实体类型 'IdentUser' 的实例,因为已经有另一个具有相同键的这种类型的实例被跟踪。
我对 ASP.NET Core 还比较陌生,我才刚刚开始了解异步调用的来龙去脉,所以我很难调试它。我已经在 SO 上搜索了答案,但没有找到任何可以解决我的问题的东西,所以我来了。关于如何修复或调试此问题的任何想法?
所以,我找出了我的问题,并发布了我的修复程序,希望可以帮助面临此问题的其他人。
我的 FindById 函数是在 AspNetCore.Identity 的 UserManager IdentUserManager
的扩展中实现的。 FindById 不是异步的 ->
public IdentUser FindById(int userId)
{
return _dbContext.Users.Include(user => user.IdentUserProfile)
.Include(role => role.IdentUserProfile.IdentUserOrgRole)
.Include(client => client.IdentUserProfile.IdentMapApplicationsWithUser).FirstOrDefault(x => x.Id == userId);
}
因此,我现在使用 AspNetCore.Identity 的 FindByIdAsync
IdentUser User = await UserManager.FindByIdAsync(passwordObj.userId.ToString());
这解决了我的问题。不完全确定原因是什么,但是直接使用 DbContexts
和异步调用似乎不太协调。有任何解释欢迎评论