我正在使用ASP.NET MVC 5 + Web API开发一个网站。其中一个要求是用户必须能够下载一个即时创建的大型zip文件。 因为我立即想要显示用户的进度,我的想法是在共振中使用带有回调的PushStreamContent。回调创建zipfile并将其流式传输到响应。
当我按照以下方式实现它时,从一个空的ASP.NET MVC + Web API项目开始,它按预期工作。一旦结果返回给客户端,就会调用回调 zipfile将流式传输到客户端。因此,一旦回调创建了zip存档并向其添加文件,用户就可以看到进度。
[RoutePrefix("api/download")]
public class DownloadController : ApiController
{
[HttpGet]
public HttpResponseMessage Get()
{
var files = new DirectoryInfo(@"c:\tempinput").GetFiles();
var pushStreamContent = new PushStreamContent(async (outputStream, httpContext, transportContext) =>
{
using (var zipOutputStream = new ZipOutputStream(outputStream))
{
zipOutputStream.CompressionLevel = CompressionLevel.BestCompression;
foreach (var file in files)
{
zipOutputStream.PutNextEntry(file.Name);
using (var stream = File.OpenRead(file.FullName))
{
await stream.CopyToAsync(zipOutputStream);
}
}
}
});
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = pushStreamContent
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") {FileName = "MyZipfile.zip"};
return response;
}
}
现在,我必须将其集成到现有网站中,该网站配置为使用Microsoft.Owin.OwinMiddleware。我使用了与上面粘贴的相同的代码,但现在行为是不同的:在创建zip文件期间,它不会流式传输到响应,而是仅在zip的创建完成时下载。因此,用户在创建文件期间看不到任何进展。
我还在我的Web API + Owin项目中尝试了不同的方法,如下所述:(generate a Zip file from azure blob storage files)。 在一个空的Asp.NET MVC项目(没有OWIN中间件)中,这完全符合预期,但是当涉及到OWIN时,我得到了这个HTTPException和stacktrace:
System.Web.HttpException:'在发送HTTP标头后,服务器无法设置状态。'
System.Web.dll!System.Web.HttpResponse.StatusCode.set(int value)未知 System.Web.dll!System.Web.HttpResponseWrapper.StatusCode.set(int value)未知 Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.OwinCallContext.Microsoft.Owin.Host.SystemWeb.CallEnvironment.AspNetDictionary.IPropertySource.SetResponseStatusCode(int value)Unknown
似乎OWIN想要设置响应状态,尽管这已经在我的Get()方法中完成(HttpResponseMessage(HttpStatusCode.OK))。
有关如何解决此问题的建议或针对不同方法的想法吗?
非常感谢!