2

I have a Web API 2 ApiController with the following GET method:

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

My custom implementation of 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);
    }
}

When I use Postman to GET, I get "No response". A breakpoint where StreamContent is created shows the stream to have a length around 1000 bytes. What have I missed?

Other similar questions but not duplicates

This question is not a duplicate, although it appears to have some siblings:

Community
  • 1
  • 1
Dr Rob Lang
  • 6,659
  • 5
  • 40
  • 60
  • Should make any real difference whether you're writing to a MemoryStream or a FileStream. – ManoDestra Jun 21 '16 at 17:12
  • 2
    You may need to reposition your memory stream to the beginning, using `memoryStream.Position = 0;` – Federico Dipuma Jun 21 '16 at 17:51
  • @Frederico Dipuma - that was the correct answer. Please create a new answer with the full code so that I may up-vote it. The position reset must be applied after the ZipArchive `using` statement has completed. – Dr Rob Lang Jun 22 '16 at 08:05

1 Answers1

3

You must reset the memoryStream position to "0" so that it doesn't try to start from the end of the file when writing to the response. The fixed code should look like this:

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);
AlbatrossCafe
  • 1,710
  • 6
  • 26
  • 49