asp.net 5 / mvc 6 中的 PushStreamContent 不起作用

2024-04-19

我正在尝试将使用 PushStreamContent 的 Web api 项目(经典 web.config 项目)迁移到最新的 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);
    }
}

如果我更改控制器操作以返回任务并将 PushStreamContent 包装在类 MyPushStreamResult 中 - 如下所示:

[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 结构的示例。


HttpResponseMessage除非您使用的是 ASP.NET 5,否则不会对其进行特殊处理Microsoft.AspNet.Mvc.WebApiCompatShim包裹。这个包是not如果您可以使用 ASP.NET 5 功能来做类似的事情,则推荐使用它,并且它是为了支持向后兼容性而创建的。

所以自从HttpResponseMessage不被认为是特殊的,它被渲染为 jsonJsonOutuptFormatter就像任何其他 .NET 对象一样

代替PushStreamContent,您当前可以直接通过以下方式访问响应流HttpContext.Response.Body属性,因此您可以直接写入流。

Updated:
PushStreamContentWeb API 允许您直接写入响应流。此类型是由 Web API 团队创建的,不作为System.Net.Http所有其他内容类型所在的库),以便可以直接写入流,例如从控制器或过滤器等。 PushStreamContent 的替代方案是StreamContent它只允许您提供一个 Stream 对象,然后主机层从源流中“复制”数据(如“拉取”数据)。 PushStreamContent 本身也没什么特别的。人们可以编写自己的类型,该类型派生于HttpContent.

总而言之,PushStreamContent允许直接写入响应流,就像在 ASP.NET 5 中一样,我们可以直接访问流,因此您可以写入它。

Updated:
在非常基本的形式(右侧,您可以转换为可测试性的操作结果),以下内容应该有效。

[HttpGet]
public Task Get()
{
    HttpContext.Response.ContentType = "text/event-stream";
    var sourceStream = // get the source stream
    return sourceStream.CopyToAsync(HttpContext.Response.Body);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

asp.net 5 / mvc 6 中的 PushStreamContent 不起作用 的相关文章

随机推荐