Comment diffuser correctement la réponse dans ASP.NET Core? Il existe un contrôleur comme celui-ci (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");
}
Les navigateurs Firefox/Edge s'affichent
Bonjour le monde
, tandis que Chrome/Postman signalent une erreur:
La page localhost ne fonctionne pas
localhost a fermé la connexion de manière inattendue.
ERR_INCOMPLETE_CHUNKED_ENCODING
P.S. Je suis sur le point de diffuser beaucoup de contenu, je ne peux donc pas spécifier l'en-tête Content-Length à l'avance.
Pour diffuser une réponse qui devrait apparaître au navigateur comme un fichier téléchargé, vous devez utiliser 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"
};
}
Il est possible de retourner null
ou EmptyResult()
(qui sont équivalents), même lors de l'écriture précédente dans Response.Body
. Cela peut être utile si la méthode retourne ActionResult
pour pouvoir utiliser facilement tous les autres résultats (par exemple BadQuery()
).
[HttpGet("test")]
public ActionResult Test()
{
Response.StatusCode = 200;
Response.ContentType = "text/plain";
using (var sw = new StreamWriter(Response.Body))
{
sw.Write("something");
}
return null;
}
Je me demandais également comment procéder, et j'ai découvert que le code de la question d'origine fonctionnait bien sur ASP.NET Core 2.1.0-rc1-final
, ni Chrome (et quelques autres navigateurs) ni l'application JavaScript n'échouent avec un tel point de terminaison).
Les choses mineures que je voudrais ajouter sont simplement définir StatusCode et fermer le flux de réponse pour que la réponse soit satisfaite:
[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!");
}
}
}
Cette question est un peu plus ancienne, mais je n'ai pas pu trouver de meilleure réponse nulle part pour ce que j'essayais de faire. J'ai compris que l'astuce consiste à ouvrir un nouveau StreamWriter pour chaque bloc de contenu que vous souhaitez écrire. Procédez simplement comme suit:
[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>");
}
};
}
vous pouvez tester avec curl en utilisant la commande suivante: curl -NX DELETE <CONTROLLER_ROUTE>/content