Wie in einigen anderen Posts erwähnt (siehe Referenzen unten), versuche ich Antwortfilter zu erstellen, um Inhalte zu ändern, die von einer anderen Webanwendung erzeugt werden.
Ich habe die grundlegende String-Transformationslogik, die funktioniert und in Filter eingekapselt ist, die von einer gemeinsamen FilterBase abgeleitet sind. Die Logik muss jedoch auf den vollständigen Inhalt und nicht auf Inhaltsblöcke angewendet werden. Daher muss ich die Chunks zwischenspeichern, während sie geschrieben werden, und den Filter ausführen, wenn alle Schreibvorgänge abgeschlossen sind.
Wie unten gezeigt, habe ich einen neuen ResponseFilter erstellt, der von MemoryStream abgeleitet wurde. Beim Schreiben wird der Inhalt in einen anderen MemoryStream zwischengespeichert. Bei Flush wird der gesamte Inhalt, der jetzt im MemoryStream ist, in eine Zeichenfolge konvertiert und die Filter-Logik wird aktiviert. Der geänderte Inhalt wird dann wieder in den ursprünglichen Stream geschrieben.
Jedoch wird bei jeder zweiten Anfrage (im Grunde, wenn ein neuer Filter instanziert wird) die Flush-Methode des vorherigen Filters ausgeführt. An diesem Punkt stürzt die Anwendung mit der _outputStream.Write () -Methode ab, da der _cachedStream leer ist.
Die Reihenfolge des Ereignisses ist wie folgt:
Es gibt ein paar Fragen, die ich habe:
Hinweis : Ich erlebe das exakt gleiche Verhalten (minus Schließen von Ereignissen), wenn ich die Close-Methode nicht überschreibe.
%Vor%Referenzen:
Dank eines Tipps von Jay, dass Flush für inkrementelle Schreibvorgänge aufgerufen wurde, konnte ich den Filter wie gewünscht ausführen, indem ich die Filterlogik nur dann durchführe, wenn der Filter schließt und noch nicht geschlossen ist. Dadurch wird sichergestellt, dass der Filter beim Schließen des Streams nur einmal gespült wird. Ich habe dies mit ein paar einfachen Feldern erreicht, _isClosing und _isClosed, wie im letzten Code unten gezeigt.
%Vor%Ich habe noch keine Antworten auf meine anderen oben genannten Fragen gefunden, daher werde ich diese Antwort zu diesem Zeitpunkt nicht als ausgenommen markieren.
Flush wird nicht explizit aufgerufen. Vielleicht wird es aufgerufen, wenn der Code erkennt, dass ein neues Objekt benötigt wird, oder vielleicht als Ergebnis eines Finalizers.
Ich denke, man kann flush nach jedem inkrementellen Schreiben aufrufen, daher bin ich mir nicht sicher, ob ein Aufruf zum Leeren sowieso eine ausreichende Anzeige für eine vollständige Nachricht ist.
Tags und Links c# stream filter flush httpresponse