11

Web API プロジェクト (従来の web.config プロジェクト) を移行しようとしており、PushStreamContent を最新の asp.net 5 Web アプリ (project.json) に使用しています。

私の問題は、PushStreamContent を動作させることができないことです。

この api コントローラーを使用すると、結果はストリームではなく json 形式になります。

[Route("api/[controller]")]
public class EventsController : Controller
{
    private static readonly ConcurrentQueue<StreamWriter> s_streamWriter = new ConcurrentQueue<StreamWriter>();

   [HttpGet]
    public HttpResponseMessage Get(HttpRequestMessage request)
    {
         HttpResponseMessage response = request.CreateResponse();
        response.Content = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(WriteToStream), "text/event-stream");
        return response;
    }

    private void WriteToStream(Stream outputStream, HttpContent headers, TransportContext context)
    {
        var streamWriter = new StreamWriter(outputStream) {AutoFlush = true};
        s_streamWriter.Enqueue(streamWriter);
    }
}

コントローラのアクションを変更してタスクを返し、クラス MyPushStreamResult で PushStreamContent をラップすると、次のようになります。

[HttpGet]
public async Task<IActionResult> Get(HttpRequestMessage request)
{
    var stream = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(WriteToStream), "text/event-stream");
    return new MyPushStreamResult(stream, "text/event-stream");
}

public class MyPushStreamResult : ActionResult
{
    public string ContentType { get; private set; }
    public PushStreamContent Stream { get; private set; }
    public MyPushStreamResult(PushStreamContent stream, string contentType)
    {
        Stream = stream;
        ContentType = contentType;
    }
    public override async Task ExecuteResultAsync(ActionContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = ContentType;
        await Stream.CopyToAsync(response.Body);
    }
}

コントローラーアクションへのリクエストはストリームを返すようになりましたが、サーバー側で閉じる前にストリームがフラッシュされていないか、大量のデータが含まれています。データを PushStreamContent 出力ストリームにプッシュすると、各テキスト書き込み後にフラッシュしますが、フラッシュは response.Body ストリームにはないと思います。

何が恋しいですか?asp.net 5 構造のサンプルが見つかりません。

4

1 に答える 1

8

HttpResponseMessageMicrosoft.AspNet.Mvc.WebApiCompatShimパッケージを使用していない限り、ASP.NET 5 では特別に扱われません。このパッケージは、ASP.NET 5 の機能を使用して同様のことを行うことができ、下位互換性をサポートするために作成されたものである場合はお勧めしません

したがって、特別と見なされていないため、他の .NET オブジェクトと同様HttpResponseMessageに によって json としてレンダリングされます。JsonOutuptFormatter

の代わりにPushStreamContent、現在、プロパティを介して直接応答ストリームにアクセスHttpContext.Response.Bodyできるため、ストリームに直接書き込むことができます。

更新:
PushStreamContentWeb API では、応答ストリームに直接書き込むことができました。このタイプは (Web API チームによって作成され、System.Net.Http他のすべてのコンテンツ タイプが存在するライブラリの一部としては存在しません)、たとえばコントローラーやフィルターなどからストリームに直接書き込むことができるように作成されました。PushStreamContent の代替はStreamContentStream オブジェクトを提供し、ホスト レイヤーがソース ストリームからデータを「コピー」することしかできませんでした (データの「プル」など)。また、PushStreamContent 自体は特別なものではありません。から派生した独自の型を書くことができますHttpContent

要約するPushStreamContentと、ASP.NET 5 のようにストリームに直接アクセスできるため、応答ストリームに直接書き込むことができるため、それに書き込むことができます。

更新:
非常に基本的な形式 (右、テスト容易性のために actionresult に変換できます) では、次のように動作するはずです。

[HttpGet]
public Task Get()
{
    HttpContext.Response.ContentType = "text/event-stream";
    var sourceStream = // get the source stream
    return sourceStream.CopyToAsync(HttpContext.Response.Body);
}
于 2015-11-24T17:10:55.693 に答える