使用Asp.net Identity Core UserManager删用户时遇无法访问已释放对象错误
问题分析与修复方案
错误原因
调用GetRolesAsync时触发“无法访问已释放对象”,核心原因是操作依赖的DbContext实例已被释放,结合代码细节来看,还存在几个潜在问题:
- 用户对象在事务范围外获取,后续操作时可能脱离原上下文跟踪
- 代码逻辑错误:删除用户后判断的是角色移除结果而非用户删除结果,会导致错误的事务提交逻辑
- 若
UserManager与DbContext生命周期配置不匹配,异步操作中也会出现上下文提前释放的情况
修复步骤
1. 调整事务范围,统一上下文操作
将用户查询逻辑移到事务using块内部,确保所有操作都在同一个事务上下文内执行:
private async Task deleteUser(string userId) { try { using (var transaction = context.Database.BeginTransaction()) { IdentityUser? user = await UserManager.FindByIdAsync(userId); if (user is not null) { IList<string> roles = await UserManager.GetRolesAsync(user); IdentityResult roleResult = await UserManager.RemoveFromRolesAsync(user, roles); if (roleResult.Succeeded) { IdentityResult identityResult = await UserManager.DeleteAsync(user); if (identityResult.Succeeded) // 修正为判断用户删除操作结果 { Snackbar.Add("Success", Severity.Success); transaction.Commit(); } } return; } } } catch (Exception ex) { Logger.LogError(ex.Message); } }
2. 校验生命周期配置
确保UserManager与DbContext的生命周期一致(ASP.NET Core中默认均为Scoped),避免因生命周期不匹配导致异步操作中上下文被提前释放。
3. 优化异常与事务回滚逻辑
添加失败场景的事务回滚,同时记录详细错误信息,方便排查问题:
private async Task deleteUser(string userId) { try { using (var transaction = context.Database.BeginTransaction()) { IdentityUser? user = await UserManager.FindByIdAsync(userId); if (user is null) { Snackbar.Add("用户不存在", Severity.Warning); return; } // 移除用户角色 IList<string> roles = await UserManager.GetRolesAsync(user); IdentityResult roleResult = await UserManager.RemoveFromRolesAsync(user, roles); if (!roleResult.Succeeded) { foreach (var error in roleResult.Errors) { Logger.LogError("移除角色失败: {Error}", error.Description); } Snackbar.Add("移除角色失败", Severity.Error); transaction.Rollback(); return; } // 删除用户 IdentityResult identityResult = await UserManager.DeleteAsync(user); if (!identityResult.Succeeded) { foreach (var error in identityResult.Errors) { Logger.LogError("删除用户失败: {Error}", error.Description); } Snackbar.Add("删除用户失败", Severity.Error); transaction.Rollback(); return; } // 提交事务 Snackbar.Add("删除成功", Severity.Success); transaction.Commit(); } } catch (Exception ex) { Logger.LogError(ex, "删除用户时发生异常"); Snackbar.Add("删除操作异常", Severity.Error); } }
内容的提问来源于stack exchange,提问作者Imtiyaz Choujai
相关产品推荐
相关产品推荐

