Ich habe vor kurzem Änderungen an meiner MVC3-Anwendung in dem Versuch, die DbContext
Objekte ordnungsgemäß zu entsorgen [1]. Dies funktionierte großartig in der Entwicklung, aber sobald die Anwendung auf meinen Produktionsserver übertragen wurde, begann ich intermittierend einige lustige Ausnahmen zu bekommen, die so lange bestehen blieben, bis der AppPool recycelt wurde. Die Ausnahmen zurück zum Code in meine Gewohnheit werden kann AuthorizeAttribute
verfolgt und wie folgt aussehen:Probleme nach der Bereitstellung von DbContext
System.InvalidOperationException: The 'Username' property on 'User' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'String'.
System.InvalidOperationException: The 'Code' property on 'Right' could not be set to a 'String' value. You must set this property to a non-null value of type 'Int32'.
(Datenbankschema sieht wie folgt aus: Benutzer: [Guid, String, ...], Rechte: [Guid, Int32. ..])
Es ist, als ob einige "Drähte werden gekreuzt", und die Anwendung verwechselt Ergebnisse aus der Datenbank: Versuchen, das Right
Ergebnis als User
und umgekehrt.
Um die Entsorgung von DbContext
zu verwalten, legte ich Code, um dies auf einer Controller-Ebene zu speichern. Wenn die Steuerung entsorgt wird, entsorgen wir auch die DbContext
. Ich weiß, es ist hacky, aber die AuthorizeAttribute
verwendet den gleichen Kontext über filterContext.Controller
.
Stimmt etwas nicht mit der Handhabung des Objektlebenszyklus DbContext
in diesem Herrenhaus? Gibt es irgendwelche logischen Erklärungen dafür, warum ich die oben genannten Ausnahmen überschreite?
[1] Obwohl ich verstehe, dass es nicht notwendig ist, DbContext
Objekte zu entsorgen, stieß ich kürzlich auf eine Anzahl von Quellen, die besagen, dass es unabhängig davon Best Practice war.
Edit (pro @ MikeSW Kommentar)
Eine Eigenschaft der AuthorizeAttribute
repräsentiert die DbContext
in den OnAuthorization
Verfahren eingestellt werden, wenn die AuthorizationContext
im Gültigkeitsbereich befindet. Diese Eigenschaft wird später in der AuthorizeCore
-Methode verwendet.
Können Sie einige der relevanten Code Ihrer benutzerdefinierten AuthorizeAttribute teilen? Beachten Sie, dass ein Attribut von asp.net mvc als Singleton verwendet wird. Verwenden Sie auch einen DI-Container? – MikeSW
@MikeSW Ich habe Informationen zur obigen Verwendung hinzugefügt. Ich verwende keinen DI-Container. Mit den Informationen, die ich oben angegeben habe, scheint es, als ob diese Fehler aufgrund von Nebenläufigkeit auftreten: In der Zeit zwischen 'OnAuthorization' und 'AuthorizeCore' löst eine andere Anfrage' OnAuthorization' aus und überlagert die 'DbContext'-Eigenschaft. Folgt das? –
Ja, das ist dein Problem. Die [Autorisieren] ist im Grunde ein Singleton und Sie ändern die dbcontext -Eigenschaft bei jeder Anfrage. Ich schlage vor, einen DI-Container zu verwenden, DbContext mit HttpPerInstance-Lebensdauer zu registrieren und dann DependencyResolver.Current.GetService() in OnAuthorization-Methode zu verwenden. Der Container sollte auch die Entsorgung von DbContext übernehmen. –
MikeSW