You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 5升级后使用ASP.NET Boilerplate遇UserManagerProxy已释放访问错误

解决Cannot access a disposed object UserManagerProxy错误(.NET5 + 旧版ABP)

我之前在升级到.NET 5 + 旧版ASP.NET Boilerplate(非ABP Framework)的时候,也碰到过一模一样的问题!当时调试的时候直接跳错误,完全摸不着头脑,后来折腾了好一阵才找到几个可行的解决方向,分享给你:

可能的原因

这个错误本质上是UserManagerProxy对象在还需要使用的时候就被DI容器给释放了,通常和异步操作的上下文管理、UnitOfWork范围或者依赖注入的生命周期配置有关。

具体解决方案

1. 调整代码执行顺序,提前初始化UserManager

你现在是在循环添加角色之后才调用InitializeOptionsAsync,建议把这个初始化操作提前到最开头,确保UserManager在整个操作过程中都处于可用状态:

// 提前初始化UserManager选项,放在所有操作之前
await _userManager.InitializeOptionsAsync(AbpSession.TenantId);

// 先获取默认角色,避免在UserManager操作中途调用其他Manager的异步方法
var defaultRoles = await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync();

// 再创建用户对象
var user = new User 
{ 
    TenantId = tenant.Id, 
    Name = name, 
    Surname = surname, 
    EmailAddress = emailAddress, 
    IsActive = true, 
    UserName = userName, 
    IsEmailConfirmed = isEmailConfirmed, 
    Roles = new List<UserRole>() 
};
user.SetNormalizedNames();

foreach (var defaultRole in defaultRoles) 
{
    user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
}

user.IsEmailConfirmed = isEmailConfirmed;
user.ShouldChangePasswordOnNextLogin = true;

CheckErrors(await _userManager.CreateAsync(user, plainPassword));
await CurrentUnitOfWork.SaveChangesAsync(); // 推荐用异步版本的SaveChanges

2. 显式包裹UnitOfWork范围

如果这段代码不在一个已有的UnitOfWork上下文中(比如在一个没有标记[UnitOfWork]的方法里),可以手动开启一个UnitOfWork,确保DbContext和相关Manager不会被提前释放:

using (var uow = UnitOfWorkManager.Begin())
{
    await _userManager.InitializeOptionsAsync(AbpSession.TenantId);
    var defaultRoles = await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync();

    var user = new User { /* 你的用户属性 */ };
    user.SetNormalizedNames();

    foreach (var defaultRole in defaultRoles) 
    {
        user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
    }

    user.IsEmailConfirmed = isEmailConfirmed;
    user.ShouldChangePasswordOnNextLogin = true;

    CheckErrors(await _userManager.CreateAsync(user, plainPassword));
    await CurrentUnitOfWork.SaveChangesAsync();
    await uow.CompleteAsync();
}

3. 检查依赖注入的生命周期配置

确保你的UserManager和RoleManager是注册为Scoped生命周期的(旧版ABP默认应该是这样,但升级过程中可能被误改)。如果被注册成Singleton,会导致它依赖的DbContext提前被释放,进而引发这个错误。

4. 检查自定义UserManagerProxy的实现

如果你项目里有自定义的UserManagerProxy类,一定要检查它的Dispose方法,有没有在不该释放的时候提前释放了内部的UserManager实例。比如有些自定义实现会在Dispose里直接释放内部对象,但如果DI容器还在使用它,就会触发这个错误。

额外提醒

升级到.NET5的时候,一定要跟着旧版ABP的官方迁移指南走,.NET5对异步操作和DI容器的生命周期管理更严格,很多之前“能用”的代码在.NET5里会暴露出资源释放的问题。另外,尽量避免在异步方法里使用同步阻塞的调用(比如.Result或者.Wait()),这也是导致上下文被提前释放的常见原因。

内容的提问来源于stack exchange,提问作者Ivan Sager

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:19:16