2016-12-19 2 views
2

Ich versuche, einen Controller zu schreiben, der eine Anfrage von einem AJAX-Aufruf empfängt und einige Aufrufe an die Datenbank über den DBContext ausführt. Wenn ich jedoch den Befehl var user = await GetCurrentUserAsynch(); vor alle Aufrufe an den DBContext, wie unten gezeigt, platzieren, erhalte ich eine ObjectDisposedException (Zugriff auf ein Objekt nicht möglich).So lösen Sie eine ausgelagerte Ausnahme ASP.NET Core mit Entity Framework und Identität

Es scheint, dass der UserManager und der DBContext nicht gut zusammenspielen, aber ich kann nicht viele Informationen zu diesem Thema finden.

[HttpPost]   
public async void EditUserMapItemAjax([FromBody]UserMapItemViewModel userMapItemViewModel) 
{    
    var user = await GetCurrentUserAsync(); 
    var mapItem = _db.MapItems.SingleOrDefault(x => x.Id == userMapItemViewModel.MapItemId); 

    ... 
} 

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User); 
+0

Welchen Provider verwenden Sie? GetUserAsync umschließt den Aufruf einfach um den zugrunde liegenden 'IUserStore ' – Tseng

+0

@Tseng Ich bin neu bei den meisten Konzepten - .net Kern, Entität und Identität, so entschuldige ich mich, wenn dies Ihre Frage nicht beantwortet. In meinem Startup.ConfigServies habe ich: 'services.AddIdentity ()' und 'services.AddScoped >();'. Anwendungsbenutzer erweitert IdentityUser. –

+0

Identität wird von einer Datenbank gesichert, und der Provider verbindet sie. Sehen Sie es als Datenbanktreiber an. Welche Datenbank verwenden Sie mit Identity? MSSQL? Sqlite? Mysql? PostgreSQL? Im UserManager gibt es keinen Code, der Anrufe abruft, sondern nur an den Provider delegiert. Der SQLServer-Provider enthält auch keine Daten, daher vermute ich, dass Sie einen anderen Anbieter verwenden. Sie müssen auch nicht 'services.AddScoped >();' manuell, Identität sollte dies bereits tun, iirc – Tseng

Antwort

14

Erklären Sie Ihre Controller-Aktion als async Task, nicht async void.

Mit letzterem sobald Ihre Methode trifft der erste await, gibt er die Kontrolle an den Anrufer, und weil ASP.NET hat jetzt keine Möglichkeit, ihre Fortschritte zu verfolgen (wie es wäre, wenn es eine Task stattdessen zurückgibt) Es stellt Ihre Controller-Instanz und (am wahrscheinlichsten) alle lokal begrenzten Felder zur Verfügung.


Während Sie es, wie Sie in einem Asynchron-Methode sind sowieso, sollten Sie die Asynchron-Version des EF Anruf bevorzugen; d. h. await _db.MapItems.SingleOrDefaultAsync()

Verwandte Themen