मैं एक लॉगिन-सिस्टम बना रहा हूं। विधि 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 मिलता है, तो शून्य विधि 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: 'एक डिस्पोजेड ऑब्जेक्ट तक नहीं पहुंच सकता। इस त्रुटि का एक सामान्य कारण एक संदर्भ का निपटान करना है जिसे निर्भरता इंजेक्शन से हल किया गया था और फिर बाद में आपके आवेदन में कहीं और उसी संदर्भ उदाहरण का उपयोग करने का प्रयास कर रहा था। यह तब हो सकता है जब आप संदर्भ पर निपटान() को कॉल कर रहे हों, या किसी प्रयोग कथन में संदर्भ को लपेट रहे हों। यदि आप निर्भरता इंजेक्शन का उपयोग कर रहे हैं, तो आपको निर्भरता इंजेक्शन कंटेनर को संदर्भ उदाहरणों को निपटाने का ध्यान रखना चाहिए। 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.
}
0
Stian 6 पद 2019, 22:05

1 उत्तर

सबसे बढ़िया उत्तर

LoginAdminUser async है, लेकिन जब आप इसे कॉल करते हैं तो आप इसकी प्रतीक्षा नहीं कर रहे होते हैं। परिणामस्वरूप, कार्रवाई की प्रक्रिया चलती रहती है और LoginAdminUser के पूरा होने से पहले वापस आ जाती है। जब कार्रवाई वापस आती है, तो संदर्भ आपको अपवाद देते हुए निपटाया जाता है।

लंबी और छोटी, कॉल की प्रतीक्षा करें:

if (au != null)
{
    await LogInAdminUser(au);
    return RedirectToLocal(loginForm.ReturnUrl ?? au.StartPage ?? "/Admin");
}
2
Chris Pratt 6 पद 2019, 22:20