web-dev-qa-db-ja.com

ASP.NET Coreでストリーミングする方法

ASP.NET Coreで応答を適切にストリーミングする方法は?次のようなコントローラーがあります(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ブラウザショー

こんにちは世界

、Chrome/Postmanはエラーを報告します:

ローカルホストページが機能していません

localhostが予期せず接続を閉じました。

ERR_INCOMPLETE_CHUNKED_ENCODING

追伸大量のコンテンツをストリーミングしようとしているため、事前にContent-Lengthヘッダーを指定できません。

17
Dmitry Nogin

ダウンロードしたファイルのようにブラウザに表示される応答をストリーミングするには、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"
  };
}
20
Stephen Cleary

以前に_Response.Body_に書き込んだ場合でも、nullまたはEmptyResult()(これらは同等)を返すことができます。メソッドがActionResultを返すと、他のすべての結果も簡単に使用できるようになります(例: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;
}
_
4
Martin Staufcik

私もこれを行う方法を疑問に思っていた、と元の質問のコードがASP.NET Core 2.1.0-rc1-final、Chrome(および他のいくつかのブラウザー)もJavaScriptアプリケーションも、そのようなエンドポイントで失敗しません。

追加したいマイナーなことは、StatusCodeを設定し、応答Streamを閉じて応答を満たすことです。

[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

この質問は少し古いですが、私がやろうとしていたことに対して、どこにも良い答えを見つけることができませんでした。トリックは、書き込みたいコンテンツのチャンクごとに新しいStreamWriterを開くことです。次の手順を実行します。

[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>");
        }
    };
}

次のコマンドを使用してcurlでテストできます:curl -NX DELETE <CONTROLLER_ROUTE>/content

0
Developer 4993