Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

373
Visualizações
How to stream with ASP.NET Core

How to properly stream response in ASP.NET Core? There is a controller like this (UPDATED 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 browsers show

Hello World

, while Chrome/Postman report an error:

The localhost page isn’t working

localhost unexpectedly closed the connection.

ERR_INCOMPLETE_CHUNKED_ENCODING

P.S. I am about to stream a lot of content, so I cannot specify Content-Length header in advance.

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

To stream a response that should appear to the browser like a downloaded file, you should use FileStreamResult:

[HttpGet]
public FileStreamResult GetTest()
{
  var stream = new MemoryStream(Encoding.ASCII.GetBytes("Hello World"));
  return new FileStreamResult(stream, new MediaTypeHeaderValue("text/plain"))
  {
    FileDownloadName = "test.txt"
  };
}
about 4 years ago · Santiago Trujillo Relatório

0

@Developer4993 was correct that to have data sent to the client before the entire response has been parsed, it is necessary to Flush to the response stream. However, their answer is a bit unconventional with both the DELETE and the Synchronized.StreamWriter. Additionally, Asp.Net Core 3.x will throw an exception if the I/O is synchronous. This is tested in Asp.Net Core 3.1:

[HttpGet]
public async Task Get()
{
    Response.ContentType = "text/plain";
    StreamWriter sw;
    await using ((sw = new StreamWriter(Response.Body)).ConfigureAwait(false))
    {
        foreach (var item in someReader.Read())
        {
            await sw.WriteLineAsync(item.ToString()).ConfigureAwait(false);
            await sw.FlushAsync().ConfigureAwait(false);
        }
    }
}

Assuming someReader is iterating either database results or some I/O stream with a large amount of content that you do not want to buffer before sending, this will write a chunk of text to the response stream with each FlushAsync(). For my purposes, consuming the results with an HttpClient was more important than browser compatibility, but if you send enough text, you will see a chromium browser consume the results in a streaming fashion. The browser seems to buffer a certain quantity at first.

Where this becomes more useful is with the latest IAsyncEnumerable streams, where your source is either time or disk intensive, but can be yielded a bit at at time:

[HttpGet]
public async Task<EmptyResult> Get()
{
    Response.ContentType = "text/plain";
    StreamWriter sw;
    await using ((sw = new StreamWriter(Response.Body)).ConfigureAwait(false))
    {
        await foreach (var item in GetAsyncEnumerable())
        {
            await sw.WriteLineAsync(item.ToString()).ConfigureAwait(false);
            await sw.FlushAsync().ConfigureAwait(false);
        }
    }
    return new EmptyResult();
}

You can throw an await Task.Delay(1000) into either foreach to demonstrate the continuous streaming.

Finally, @StephenCleary 's FileCallbackResult works the same as these two examples as well. It's just a bit scarier with the FileResultExecutorBase from deep in the bowels of the Infrastructure namespace.

[HttpGet]
public IActionResult Get()
{
    return new FileCallbackResult(new MediaTypeHeaderValue("text/plain"), async (outputStream, _) =>
    {
        StreamWriter sw;
        await using ((sw = new StreamWriter(outputStream)).ConfigureAwait(false))
        {
            foreach (var item in someReader.Read())
            {
                await sw.WriteLineAsync(item.ToString()).ConfigureAwait(false);
                await sw.FlushAsync().ConfigureAwait(false);
            }
        }
        outputStream.Close();
    });
}

about 4 years ago · Santiago Trujillo Relatório

0

It is possible to return null or EmptyResult() (which are equivalent), even when previously writing to Response.Body. It may be useful if the method returns ActionResult to be able to use all the other results aswell (e.g. BadQuery()) easily.

[HttpGet("test")]
public ActionResult Test()
{
    Response.StatusCode = 200;
    Response.ContentType = "text/plain";
    using (var sw = new StreamWriter(Response.Body))
    {
        sw.Write("something");
    }
    return null;
}
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda