2016-04-27 6 views
0

Ich habe folgende Middleware-Code:Kann eine Owin Middleware eine Antwort zurückgeben, bevor die Methode Invoke zurückgibt?

public class UoWMiddleware : OwinMiddleware 
{ 
    readonly IUoW uow; 
    public UoWMiddleware(OwinMiddleware next, IUoW uow) : base(next) 
    { 
     this.uow = uow; 
    } 

    public override async Task Invoke(IOwinContext context) 
    { 
     try 
     { 
      await Next.Invoke(context); 
     } 
     catch 
     { 
      uow.RollBack(); 
      throw; 
     } 
     finally 
     { 
      if (uow.Status == Base.SharedDomain.UoWStatus.Running) 
      { 
       var response = context.Response; 
       if (response.StatusCode < 400) 
       { 
        Thread.Sleep(1000); 
        uow.Commit(); 
       } 
       else 
        uow.RollBack(); 
      } 
     } 
    } 
} 

Gelegentlich beobachten wir, dass die Antwort kehrt zum Client vor uow.Commit() über Fiedler aufrufen. Zum Beispiel setzen wir einen Unterbrechungspunkt auf uow.Commit und wir sehen, dass die Antwort an den Client zurückgegeben wird, obwohl wir auf dem Haltepunkt warten. Das ist etwas unerwartet. Ich würde denken, dass die Antwort nach dem Ende der Invoke-Methode genau zurückkehrt. Fehle ich etwas?

Antwort

1

In Owin/Katana die Reaktionskörper (und natürlich die Header) werden in dem Augenblick an den Client gesendet wird, wenn eine Middleware auf der WriteResponse Aufgabe der IOwinContext aufruft.

Dies bedeutet, dass wenn Ihre nächste Middleware den Antworttext schreibt, wird Ihr Client es erhalten, bevor Ihr serverseitiger Code vom Aufruf an await Next.Invoke() zurückkehrt.

So wird Owin entworfen und hängt davon ab, dass der Antwortstream nur einmal in einem einzigen Request/Response-Lebenszyklus geschrieben werden kann.

Wenn Sie Ihren Code betrachten, kann ich in diesem Verhalten kein größeres Problem feststellen, da Sie einfach die Antwortheader lesen, nachdem die Antwort in den Stream geschrieben wurde, und sie somit nicht ändert.

Wenn Sie stattdessen die von Ihrer nächsten Middleware geschriebene Antwort ändern müssen oder Sie unbedingt die Antwort nach schreiben müssen, führen Sie weitere logische Server-Seite aus, dann besteht die einzige Möglichkeit darin, den Antworttextkörper zu puffern ein Speicher-Stream, und dann kopieren Sie es in den realen Antwort-Stream (as per this answer), wenn Sie bereit sind.

Ich habe diesen Ansatz erfolgreich in einem anderen Anwendungsfall getestet (aber das gleiche Konzept Sharing), die Sie bei dieser Antwort suchen finden kann: https://stackoverflow.com/a/36755639/3670737

Referenz:
Changing the response object from OWIN Middleware

+0

Lassen Sie mich etwas klarstellen. Ich beobachte, dass die Antwort "abgeschlossen" ist, bevor meine owin-Methode zurückkehrt. Also sagen Sie, dass dies beabsichtigt ist? –

+1

Ja, die Antwort wird im selben Moment gesendet, in dem eine Middleware 'Write' aufruft, und das, nehme ich an, passiert innerhalb Ihrer * nächsten * Middleware (z.B. Web-API). Aus diesem Grund sehen Sie die HTTP-Antwort in Fiddler, bevor Ihre Methode zurückkehrt. –

+0

Ja anscheinend hast du recht. In meinem Fall wollte ich nur auf die Momentantwort zugreifen. Also OnSendingHeaders Callback ist was ich will. Dein Beitrag führte mich in die richtige Richtung. –