我正在创建一个登录系统。方法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.
}
LoginAdminUser
是异步的,但在调用它时并没有等待它。结果,动作的处理持续进行并在LoginAdminUser
完成之前返回。当操作返回时,将处理上下文,并为您提供例外。