wake-up-neo.com

So streamen Sie mit ASP.NET Core

Wie streame ich die Antwort in ASP.NET Core richtig? Es gibt einen Controller wie diesen (PDATED CODE):

[HttpGet("test")]
public async Task GetTest()
{
    HttpContext.Response.ContentType = "text/plain";
    using (var writer = new StreamWriter(HttpContext.Response.Body))
        await writer.WriteLineAsync("Hello World");            
}

Firefox/Edge-Browser zeigen

Hallo Welt

, während Chrome/Postman einen Fehler meldet:

Die localhost-Seite funktioniert nicht

localhost hat die Verbindung unerwartet geschlossen.

ERR_INCOMPLETE_CHUNKED_ENCODING

P.S. Ich bin dabei, eine Menge Content zu streamen, daher kann ich den Content-Length-Header nicht im Voraus angeben.

17
Dmitry Nogin

Um eine Antwort zu streamen, die dem Browser wie eine heruntergeladene Datei angezeigt werden soll, sollten Sie FileStreamResult verwenden:

[HttpGet]
public FileStreamResult GetTest()
{
  var stream = new MemoryStream(Encoding.ASCII.GetBytes("Hello World"));
  return new FileStreamResult(stream, new MediaTypeHeaderValue("text/plain"))
  {
    FileDownloadName = "test.txt"
  };
}
20
Stephen Cleary

Es ist möglich, null oder EmptyResult() (die äquivalent sind) zurückzugeben, auch wenn zuvor in Response.Body Geschrieben wurde. Es kann nützlich sein, wenn die Methode ActionResult zurückgibt, um auch alle anderen Ergebnisse (z. B. BadQuery()) problemlos verwenden zu können.

[HttpGet("test")]
public ActionResult Test()
{
    Response.StatusCode = 200;
    Response.ContentType = "text/plain";
    using (var sw = new StreamWriter(Response.Body))
    {
        sw.Write("something");
    }
    return null;
}
4
Martin Staufcik

Ich habe mich auch gefragt, wie ich das machen soll, und habe herausgefunden, dass der Code der ursprünglichen Frage bei ASP.NET Core 2.1.0-rc1-final, Weder bei Chrome (und wenigen anderen Browsern) noch bei JavaScript-Anwendungen in Ordnung ist Scheitern Sie nicht mit einem solchen Endpunkt.

Kleinigkeiten, die ich hinzufügen möchte, sind nur das Setzen von StatusCode und das Schließen des Antwort-Streams, damit die Antwort erfüllt wird:

[HttpGet("test")]
public void Test()
{
    Response.StatusCode = 200;
    Response.ContentType = "text/plain";
    using (Response.Body)
    {
        using (var sw = new StreamWriter(Response.Body))
        {
            sw.Write("Hi there!");
        }
    }
}
2
ivandz

Diese Frage ist etwas älter, aber ich konnte nirgendwo eine bessere Antwort für das finden, was ich versuchte zu tun. Ich habe herausgefunden, dass der Trick darin besteht, einen neuen StreamWriter für jeden Teil des Inhalts zu öffnen, den Sie schreiben möchten. Mach einfach folgendes:

[HttpDelete]
public void Content()
{
    Response.StatusCode = 200;
    Response.ContentType = "text/html";

    // the easiest way to implement a streaming response, is to simply open a new stream writer every time
    // you have new data to write. When the writer is closed, the data will be sent to the client.
    foreach (var item in new int[] { 1, 2, 3, 4, })
    {
        using (var sw = new StreamWriter(Response.Body))
        {
            Thread.Sleep(1000);
            sw.Write($"<p>Hi there {item}!</p>");
        }
    };
}

mit dem folgenden Befehl können Sie die Locke testen: curl -NX DELETE <CONTROLLER_ROUTE>/content

0
Developer 4993