2015-10-21 11 views
12

schrieb ich meine benutzerdefinierte Middleware, die ich inZugriff auf DbContext in Middleware in ASP.NET 5

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    //... 
    app.UseAutologin(); 
    app.UseMvc(routes => 
    { 
     //... 

hinzufügen So ist es die letzte Middleware vor dem Mvc ins Spiel kommt.

In meiner Middleware Invoke Methode möchte ich (indirekt) auf die DbContext zugreifen.

public async Task Invoke(HttpContext context) 
    { 
    if (string.IsNullOrEmpty(context.User.Identity.Name)) 
    { 
     var applicationContext = _serviceProvider.GetService<ApplicationDbContext>(); 
     var signInManager = _serviceProvider.GetService<SignInManager<ApplicationUser>>(); 
     var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false); 
    } 

    await _next(context); 
    } 

Fast jedes Mal, wenn ich die folgende Ausnahme:

InvalidOperationException: Es wurde versucht, den Kontext zu verwenden, während es konfiguriert wird. Eine DbContext Instanz kann nicht verwendet werden innerhalb OnConfiguring, da es noch an diesem Punkt konfiguriert ist.

Nun wird dies deutlich durch die PasswordSignInAsync Methode aufgeworfen. Aber wie kann ich sicherstellen, dass das Modell erstellt wurde, bevor Sie solche Dinge tun?

Vielleicht war ich nicht ganz klar: Ich möchte nicht die DbContext selbst verwenden - die PasswordSignInAsync verwendet es bei der Überprüfung des Benutzers und des Passworts.

+0

ich einige Fehler haben . Hast du bitte eine Korrektur gefunden? – aguetat

+0

Was versuchen Sie zu erreichen? – mayu

Antwort

5

Was ist, wenn Sie die ApplicationDbContext und SignInManager<ApplicationUser> durch die Invoke Methode injizieren:

public async Task Invoke(HttpContext context, ApplicationDbContext applicationContext, SignInManager<ApplicationUser> signInManager) 
{ 
    if (string.IsNullOrEmpty(context.User.Identity.Name)) 
    { 
     var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false); 
    } 

    await _next(context); 
} 

diese Weise können Sie die Dienste aus dem richtigen Umfang gelöst werden. Ich bemerke, dass Sie die ApplicationDbContext nirgendwo verwenden, nur die SignInManager. Brauchst du es wirklich?

+0

Der 'SignInManager' verwendet es, deshalb bekomme ich den Fehler ... –

1

Dieser Fehler tritt wahrscheinlich auf, weil jede Middleware als Singleton fungiert. Sie müssen die Verwendung von Mitgliedsvariablen in Ihrer Middleware vermeiden. Fühlen Sie sich frei, in den Task Invoke zu injizieren, aber speichern Sie den inject-Wert nicht in einem Member-Objekt.

See: Saving HttpContext Instance in Middleware, Calling services in Middleware

konnte ich mich, dies umgehen, indem Sie eine Klasse erstellen, die ich dann in andere Methoden in meiner Middleware passieren könnte:

public async Task Invoke(HttpContext context, IMetaService metaService) 
    { 
      var middler = new Middler 
      { 
       Context = context, 
       MetaService = metaService 
      }; 

      DoSomething(middler); 
    }