Nateous
Nateous

Reputation: 787

Download ZipArchive from c# web api method returns "net::ERR_CONNECTION_RESET" in chrome

I want to call a web api method and have it allow the user to download a zip file that I create in memory. I also want to create the entries in memory as well.

I'm having trouble getting the server to correctly output the download.

Here is my web api method:

[HttpGet]
[Route("api/downloadstaffdata")]
public HttpResponseMessage DownloadStaffData()
{
    var response = new HttpResponseMessage(HttpStatusCode.OK);
    using (var stream = new MemoryStream())
    {
        using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
        {
            //future for loop to create entries in memory from staff list
            var entry = archive.CreateEntry("bob.txt");
            using (var writer = new StreamWriter(entry.Open()))
            {
                writer.WriteLine("Info for: Bob");
            }
            //future add staff images as well
        }
        stream.Seek(0, SeekOrigin.Begin);
        response.Content = new StreamContent(stream);
    }
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
    {
        FileName = "staff_1234_1.zip"
    };
    response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip");

    return response;
}

Here is my calling js code:

window.open('api/downloadstaffdata');

Here is the response from Chrome:

net::ERR_CONNECTION_RESET

I don't know what I'm doing wrong. I've already searched SO and read the articles about creating the zip file, but I can't get passed the connection reset error when trying to return the zip archive to the client.

Any ideas?

Upvotes: 2

Views: 2856

Answers (1)

ShuberFu
ShuberFu

Reputation: 709

You have your memory stream inside a using block. As such, your memory stream are being disposed before your controller has the chance to write it out (hence the ERR_CONNECTION_RESET).

A MemoryStream does not need to be disposed explicitly (its various derived type may need to be, but not the MemoryStream itself). Garbage Collector can clean it up automatically.

Upvotes: 5

Related Questions