无法访问已处置的对象。但是我只是创建了对象,并试图将其保存到代码的下一行

问题描述 投票:0回答:1

我正在创建一个登录系统。方法CheckCredentials()从登录表单获取数据:

public async Task<IActionResult> CheckCredentials(LoginFormViewModel loginForm)
{
    if (loginForm == null) return NotFound();

    AdminUser au = await db.AdminUsers
        .Include(p => p.Person)
        .Where(u =>
            u.Person.Email1 == loginForm.UserName &&
            u.Password == loginForm.Password)
        .FirstOrDefaultAsync().ConfigureAwait(false);
    if (au != null)
    {
        LogInAdminUser(au);
        return RedirectToLocal(loginForm.ReturnUrl ?? au.StartPage ?? "/Admin");
    }

    TempData["Message"] = "No such combination of username and password exists. Please try again.";
    return RedirectToAction("Login", new { loginForm.ReturnUrl });
}

如果找到与给定凭据匹配的AdminUser,则调用void方法LogInAdminUser()

private async void LogInAdminUser(AdminUser au)
{
    HttpContext.Session.SetInt32("AdminUserId", au.Id);
    Login login = new Login
    {
        PersonId = au.PersonId,
        AdminUserId = au.Id,
        LogInTime = DateTime.Now,
        RemoteIpAddress = "some string",
        Browser = "some string"
    };
    db.Add(login);
    await db.SaveChangesAsync().ConfigureAwait(false); // This line causes the exception below
    return;
}

SaveChangesAsync()抛出此异常:

System.ObjectDisposedException:'无法访问已处置的对象。导致此错误的常见原因是,处理从依赖项注入中解决的上下文,然后稍后尝试在应用程序的其他位置使用相同的上下文实例。如果在上下文上调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。如果使用依赖项注入,则应让依赖项注入容器负责处理上下文实例。ObjectDisposed_ObjectName_Name'

Login级:

public class Login
{
    public int Id { get; set; }
    public int PersonId { get; set; }
    public int? AdminUserId { get; set; }
    public DateTime LogInTime { get; set; }
    public string RemoteIpAddress { get; set; }
    public string Browser { get; set; }
    public AdminUser AdminUser { get; set; }
}

这里发生了什么?我没有在代码中的任何地方Dispose

更新

这是我创建数据库上下文的方式:

public class AdminController : BaseController
{
    private readonly KlubbNettContext db;
    private readonly IMapper auto;

    public AdminController(KlubbNettContext context, IMapper mapper, IHostingEnvironment env) : base(env)
    {
        db = context;
        auto = mapper;
    }

    // The rest of the controller methods here.
    // Both CheckCredentials() and LogInAdminUser() are among the
    // methods of this controller.
}
c# asp.net-core-mvc asp.net-core-2.2
1个回答
1
投票

LoginAdminUser是异步的,但在调用它时并没有等待它。结果,动作的处理持续进行并在LoginAdminUser完成之前返回。当操作返回时,将处理上下文,并为您提供例外。

© www.soinside.com 2019 - 2024. All rights reserved.