Warum kann ich nicht Lesen Http-Request-Eingabe-stream doppelt?

Ich war putting in einige debugging-code zu testen, einige Dinge, und dann wird der debug-code sich nicht so Verhalten wie erwartet. Das nachfolgende Beispiel zeigt einen vereinfachten code zu demonstrieren, meine Frage.

Dies ist in .NET 4 und mit WebApi, ich versuche, drucken Sie den body der http-Anfrage in der debug-code. Um dies zu tun, die ich Suche, der Eingabe-stream zurück und Lesen Sie den stream. Es funktioniert gut, beim ersten mal, aber wenn ich versuchen, es erneut zu Lesen, bekomme ich einen leeren string.

Warum kann ich nicht versuchen Sie zurück und Lesen Sie den InputStream ein zweites mal? Im Beispiel unten, body2 ist immer leer. Im zweiten Satz, CanSeek ist immer noch wahr und der zweite Aufruf ReadToEnd() einen leeren string zurück und überschreiben Sie die Standardeinstellung.

using System.IO;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

public class TestController : ApiController
{

    public class TestOutuput
    {
        public string firstRead;
        public string secondRead;
    }

    public HttpResponseMessage Post()
    {
        string body1 = "default for one";
        string body2 = "default for two";
        if (HttpContext.Current.Request.InputStream.CanSeek)
        {
            HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
        }
        using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            body1 = reader.ReadToEnd();
        }

        if (HttpContext.Current.Request.InputStream.CanSeek)
        {
            HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
        }
        using (var reader2 = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            //this is always empty, even after seek back to origin
            body2 = reader2.ReadToEnd();
        }

        TestOutuput testOutput = new TestOutuput() { firstRead = body1, secondRead = body2 };
        HttpResponseMessage response = new HttpResponseMessage();
        return Request.CreateResponse<TestOutuput>(HttpStatusCode.OK, testOutput);
    }
}
Gut funktioniert CanSeek zurück true? Du bist derzeit bedingt zu suchen, sondern dann unter der Annahme, dass das suchen funktioniert hat. Warum sind Sie noch dabei? Ich persönlich würde erwarten, dass zumindest für die große Anfrage Gremien der stream kann nicht im Arbeitsspeicher gepuffert werden. Wenn Sie möchten, erstellen Sie eine Kopie, ich schlage vor, Sie tun, die erste und Lesen Sie dann mehrere Male von Ihrer Kopie. Verwenden Stream.CopyTo in Verbindung mit einem MemoryStream.
Ja, CanSeek nicht true zurück und die ReadToEnd ausgeführt wird. Gut, Punkt. Ich werde zu aktualisieren, die Frage zu klären.
Haben Sie versucht, Fiddler?
Sie können kopieren Sie den stream in ein MemoryStream-wie Jon darauf hingewiesen, aber der Stream-Schnittstelle in einer web-Anfrage ist wirklich nur eine Abstraktion des TCP-stream nicht unterstützt, ist alle zu möglichen TCP-Operationen, die Sie durchführen können über die Steckdose (das heißt Sie könnte anfordern, dass das Paket erneut gesendet werden--aber Sie kaum jemals tun wollen, wenn Sie wollen einfach nur, um erneut die Daten zu Lesen).
Alle guten Ratschläge, danke.

InformationsquelleAutor Michael Levy | 2014-02-23

Schreibe einen Kommentar