错误:无法访问已处置的对象。此错误的一个常见原因是处理从依赖注入中解析的上下文

Posted

技术标签:

【中文标题】错误:无法访问已处置的对象。此错误的一个常见原因是处理从依赖注入中解析的上下文【英文标题】:Error: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection 【发布时间】:2020-04-25 22:38:56 【问题描述】:

我正在 .NET Core 2.2 上开发应用程序并遇到了问题:

我查看了以下链接,但这些链接似乎不起作用:

Cannot access a disposed object in ASP.NET Core when injecting DbContext Cannot access a disposed object. A common cause of this error is disposing a context https://thinkrethink.net/2017/12/22/cannot-access-a-disposed-object-in-asp-net-core-when-injecting-dbcontext/

这是我的代码:

public class UserAccountController : BaseController

    private readonly UserAccountBL _userAccountBL;

    public UserAccountController(IConfiguration configuration,
                      ILogger<UserAccountBL> logger, ApplicationDbContext db, UserManager<AppUser> accountManager)
    
        _userAccountBL = new UserAccountBL(configuration,logger,db, accountManager);
    

    [HttpPost("addnewUser")]
    public async Task<IActionResult> AddNewUser(UserVM user)
    
        try
        
            var result = _userAccountBL.AddUser(user);
            return Ok(result);
        
        catch(NotFoundException e)
        
            return Ok(new NotFoundError(e.Message));
        
    


public class DeliveryManagerAccountBL

    private readonly IConfiguration _configuration;
    private readonly ILogger<UserAccountBL> _logger;
    private readonly ApplicationDbContext _context;
    private readonly UserManager<AppUser>_accountManager;

    public UserAccountBL(IConfiguration configuration,
                      ILogger<UserAccountBL> logger, ApplicationDbContext db, UserManager<AppUser> accountManager)
    
        _configuration  = configuration;
        _logger         = logger;
        _context        = db;
        _accountManager = accountManager;
    

    public async Task<bool> AddUser( AddRiderVM user)
    
        if (CheckEmailExist(model.EmailAddress))
        
            throw new InvalidOperationException("Email already exist");
        
        if (CheckPhoneExist(model.MobileNumber))
        
            throw new InvalidOperationException("Mobile number already exist");
        

        var newUserID = Guid.NewGuid().ToString();
        var user = new AspNetUser
        
            UserName = user.EmailAddress,
            Email = user.EmailAddress,
            Id = newUserID,
            PhoneNumber = user.MobileNumber
        ;

        var password = "Dumy123@";

        try
        
            List<string> roles = new List<string>();

            **var result = await _accountManager.CreateAsync(user, password);**
          
            if (result.Succeeded)
            
              //Something will happen
            
        
        catch(Exception ex)
        
            Console.WriteLine(ex.Message);
        
        return false;
    

以下是我的 Program.cs 文件:

public class Program

    public static void Main(string[] args)
    
       var host = CreateWebHostBuilder(args).Build();

        //seed database
        using (var scope = host.Services.CreateScope())
        
            var services = scope.ServiceProvider;

            try
            
                var databaseInitializer = services.GetRequiredService<IDatabaseInitializer>();
                databaseInitializer.SeedAsync().Wait();
            
            catch (Exception ex)
            
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogCritical(LoggingEvents.INIT_DATABASE, ex, LoggingEvents.INIT_DATABASE.Name);

                throw new Exception(LoggingEvents.INIT_DATABASE.Name, ex);
            
        
        host.Run();
    

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();

以下异常发生在**行。

无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。 对象名称:'ApplicationDbContext'。

堆栈跟踪:

at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__53.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.<CreateAsync>d__22.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.AspNetCore.Identity.UserManager`1.<CreateAsync>d__74.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.AspNetCore.Identity.UserManager`1.<CreateAsync>d__79.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at StilaarApi.Core.AccountManager.<CreateUserAsync>d__10.MoveNext() in D:\project stilaar\pinchapi\Core\AccountManager.cs:line 106

【问题讨论】:

发布异常文本(全文,而不仅仅是消息)和 DI 配置代码。播种代码根本不重要。如果 DeliveryManagerAccountBLDbContext 的作用域内注册为单例,您将收到此异常。异常文本,尤其是堆栈跟踪,显示了错误实际发生的位置以及所涉及的方法 var result = await _accountManager.CreateAsync(user, password); 这会产生错误 【参考方案1】:

我在调用函数时错过了 await 关键字 等待 _userAccountBL.AddUser(user);

【讨论】:

以上是关于错误:无法访问已处置的对象。此错误的一个常见原因是处理从依赖注入中解析的上下文的主要内容,如果未能解决你的问题,请参考以下文章

无法访问已处置的对象。对象名称:'System.Net.Sockets.UdpClient'

尝试在 Web API Core 中使用 EF Core 在启动时更新数据库时出现“'无法访问已处置的对象”错误

如何调试 dotnet ef 数据库删除?

无法访问已处置的对象 VC++ VS2017 Professional

通过 Azure 函数注入 DbContext 时无法访问已处置的对象

C#:使用 IQueryable 注入 DbContext 时,无法访问 ASP.NET Core 中的已处置对象