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

调用RoleManager.RoleExistsAsync时出现已释放上下文实例访问错误

解决ASP.NET Core Web API初始化角色时"Cannot access a disposed context instance"错误

核心原因

Web API模板的启动流程与空白API模板存在差异,导致RoleManager依赖的DbContext实例在SeedAsync执行前已被容器释放。而空白模板启动逻辑更简单,未触发作用域提前释放的问题。

解决步骤

  1. 在作用域内执行初始化逻辑
    不要直接在Program.cs中调用SeedAsync,通过创建服务作用域确保DbContext和相关服务的生命周期有效:

    var app = builder.Build();
    
    // 创建作用域执行初始化
    using (var scope = app.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            await CreateRoles.SeedAsync(services);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "角色/用户初始化失败");
        }
    }
    
    // 继续配置中间件
    app.UseHttpsRedirection();
    app.UseAuthorization();
    app.MapControllers();
    
    app.Run();
    
  2. 正确获取SeedAsync中的服务
    从传入的IServiceProvider中获取RoleManager和UserManager,避免手动创建服务实例导致生命周期混乱:

    public static class CreateRoles
    {
        public static async Task SeedAsync(IServiceProvider serviceProvider)
        {
            var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
    
            // 角色初始化逻辑
            var roleNames = new[] { "Admin", "User" };
            foreach (var roleName in roleNames)
            {
                if (!await roleManager.RoleExistsAsync(roleName))
                {
                    await roleManager.CreateAsync(new IdentityRole(roleName));
                }
            }
    
            // 用户初始化逻辑示例
            var adminUser = await userManager.FindByEmailAsync("admin@example.com");
            if (adminUser == null)
            {
                var newAdmin = new IdentityUser { UserName = "admin@example.com", Email = "admin@example.com" };
                await userManager.CreateAsync(newAdmin, "Admin@123");
                await userManager.AddToRoleAsync(newAdmin, "Admin");
            }
        }
    }
    
  3. 确认DbContext的注入生命周期
    确保DbContext使用默认的Scoped生命周期注入,不要改为Transient或Singleton:

    builder.Services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
    
  4. 避免在启动早期获取Scoped服务
    不要在builder.Build()之前尝试获取RoleManager、UserManager这类依赖Scoped服务的实例,此时容器尚未创建有效作用域,获取到的服务会提前被释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:05:03