【发布时间】:2025-12-01 09:10:02
【问题描述】:
我有以下正在生成文件的操作:
public async Task<IActionResult> GetFile()
{
//some long running action to actually generate the content
//(e.g. getting data from DB for reporting)
await Task.Delay(10000);
return File(new byte[]{}, "application/octet-stream");
}
问题在于,当用户点击该链接时,在点击某个操作和浏览器显示文件正在下载之间存在很长的延迟。
我真正想要的是 ASP.Net 发送带有文件名的标题(这样浏览器会向用户显示文件已开始下载)并在生成文件内容时延迟发送正文。可以这样做吗?
我尝试了以下方法:
public async Task GetFile()
{
HttpResponse response = this.HttpContext.Response;
response.ContentType = "application/octet-stream";
response.Headers["Content-Disposition"] = "inline; filename=\"Report.txt\"";
//without writing the first 8 bytes
//Chrome doesn't display the file as being downloaded
//(or ASP.Net doesn't actually send the headers).
//The problem is, I don't know the first 8 bytes of the file :)
await response.WriteAsync(string.Concat(Enumerable.Repeat("1", 8)));
await response.Body.FlushAsync();
await Task.Delay(10000);
await response.WriteAsync("1234567890");
}
上面的代码可以正常工作,如果我不必 response.WriteAsync 发送标头的前 8 个字节,我会很高兴的。
还有其他方法可以克服吗?
【问题讨论】:
-
我可以发誓有某种类型可以让您返回某种类型的
FileContentResult,您实际上承诺提供对Stream之类的对象的访问,它可以从中提取字节因为它已准备好通过电线发送它们,但我现在找不到它。我想如果我只是梦想它,您可以自己实现一些Stream之类的东西来封装“当网络为它们准备好时我将提供字节”的想法。 -
File将enablePartialContent的第三个参数设置为true,看看它是否有效。 -
有 FileStreamResult (github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/…),但是根据源代码它会读取流直到结束并退出(即如果流中没有数据,它将立即退出,而无需等待流填充数据)
-
@Damien_The_Unbeliever 我想你可能指的是
PushStreamContent。 -
Stephen Cleary 写了一篇可能有帮助的帖子:Streaming Zip on ASP.NET Core。显然,这是关于编写 .zip,但这些概念应该适用于您的用例。
标签: c# asp.net asp.net-core httpresponse