C# 如何在内存中构建ZipArchive并通过Web API 2中的IHttpActionResult下载?

C# 如何在内存中构建ZipArchive并通过Web API 2中的IHttpActionResult下载?,c#,asp.net-web-api,C#,Asp.net Web Api,我有一个Web API 2ApiController,使用以下GET方法: [HttpGet] public IHttpActionResult GetZip() { return new ZipFileActionResult(); } 我的IHttpActionResult public class ZipFileActionResult : IHttpActionResult { public Task<HttpResponseMessage> Execute

我有一个Web API 2
ApiController
,使用以下GET方法:

[HttpGet]
public IHttpActionResult GetZip()
{
    return new ZipFileActionResult();
}
我的
IHttpActionResult

public class ZipFileActionResult : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var memoryStream = new MemoryStream();
        var response = new HttpResponseMessage(HttpStatusCode.OK);

        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            var entry = archive.CreateEntry("MyFileName.txt");

            using (var streamWriter = new StreamWriter(entry.Open()))
            {
                streamWriter.Write("It was the best of times, it was the worst of times...");
            }

        }

        response.Content = new StreamContent(memoryStream);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "example.zip"
        };
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
        return Task.FromResult(response);
    }
}
公共类ZipFileActionResult:IHttpActionResult
{
公共任务执行同步(CancellationToken CancellationToken)
{
var memoryStream=新的memoryStream();
var响应=新的HttpResponseMessage(HttpStatusCode.OK);
使用(var archive=new ZipArchive(memoryStream,ZipArchiveMode.Create,true))
{
var entry=archive.CreateEntry(“MyFileName.txt”);
使用(var streamWriter=newstreamwriter(entry.Open()))
{
streamWriter.Write(“这是最好的时代,也是最糟糕的时代……”);
}
}
response.Content=新的流内容(memoryStream);
response.Content.Headers.ContentDisposition=新的ContentDispositionHeaderValue(“附件”)
{
FileName=“example.zip”
};
response.Content.Headers.ContentType=新的MediaTypeHeaderValue(“应用程序/zip”);
返回Task.FromResult(响应);
}
}
当我使用邮递员获取信息时,我会得到“无响应”。创建
StreamContent
的断点显示流的长度约为1000字节。我错过了什么

其他类似问题,但不重复 这个问题不是重复的,尽管它似乎有一些兄弟姐妹:

  • 但是我没有保存到windows,所以我没有文件流。我还确保流在
    ZipArchive
    释放后保持打开状态
  • 但我并不是直接写到
    HttpContext.OutputStream
    ,因为我要流到
    StreamContent
    ,我可以使用更简单的
    MemoryStream

必须将
memoryStream
位置重置为“0”,以便在写入响应时不会尝试从文件末尾开始。固定代码应如下所示:

using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
    var entry = archive.CreateEntry("MyFileName.txt");

    using (var streamWriter = new StreamWriter(entry.Open()))
    {
        streamWriter.Write("It was the best of times, it was the worst of times...");
    }
}

//ADD THIS LINE
memoryStream.Position = 0;    

response.Content = new StreamContent(memoryStream);

无论您是在写入MemoryStream还是在写入文件流,都应该有真正的区别。您可能需要使用
MemoryStream.Position=0将内存流重新定位到开头@Frederico Dipuma-这是正确的答案。请用完整的代码创建一个新的答案,这样我就可以投票了。位置重置必须在ZipArchive
using
语句完成后应用。