我试图迁移一个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结构找不到任何样本。
答案 0 :(得分:6)
HttpResponseMessage
包,否则不会在ASP.NET 5中专门处理 Microsoft.AspNet.Mvc.WebApiCompatShim
。如果您可以使用ASP.NET 5功能执行类似操作并且创建它以支持向后兼容性,则此包不是 。
因为HttpResponseMessage
不被认为是特殊的,它被JsonOutuptFormatter
呈现为json,就像任何其他.NET对象一样
您目前可以通过PushStreamContent
属性直接访问响应流,而不是HttpContext.Response.Body
,因此您可以直接写入流。
<强>更新强>:
Web API中的PushStreamContent
允许您直接写入响应流。此类型是由Web API团队创建的,并不作为System.Net.Http
库的一部分存在,其中所有其他内容类型都是如此),以便可以直接写入流,例如,从控制器或过滤器等。 PushStreamContent的替代方法是StreamContent
,它只允许您提供Stream对象,然后主机层“复制”源流中的数据(如“拉”数据)。此外,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);
}