FunctionMonkey icon indicating copy to clipboard operation
FunctionMonkey copied to clipboard

How to download a zip file

Open StickNitro opened this issue 5 years ago • 5 comments

How can I set up a function that will download a Zip file to the client when completed?

I have a function that will generate multiple PDF documents and would like to return a Zip file container each of the created PDF documents to the client, do you have any examples?

StickNitro avatar Mar 20 '19 14:03 StickNitro

Ok, so I have found out that the generated functions return type is Task<IActionResult> and from experimenting, I have been able to return a FileContentResult from my command/handler which returns the base64 encoded file content.

I have not been able to successfully return a FileStreamResult as I get the exception below and cannot determine if this is supported or not

Newtonsoft.Json: Error getting value from 'ReadTimeout' on 'System.IO.FileStream'. System.Private.CoreLib: Timeouts are not supported on this stream.

StickNitro avatar Mar 20 '19 15:03 StickNitro

Have you got some sample code I could use to investigate?

JamesRandall avatar Mar 22 '19 20:03 JamesRandall

Yeah I was basically creating an in-memory Zip file and wanting to return that from the function, the code snippet below should help you

using (var ms = new MemoryStream())
{
  using (var archive = new ZipArchive(ms, ZipArchiveMode.Update, true))
  {
    // add entries to the zip file

    if (archive.Entries.Count > 0)
    {
      archive.Dispose();
      ms.Seek(0, SeekOrigin.Begin);
      return new FileStreamResult(ms, "application/pdf");
    }
  }
}

StickNitro avatar Mar 27 '19 09:03 StickNitro

Great thank you - I'll be doing some work on Function Monkey this weekend and I'll add this to that list: either a bug fix or a solution!

JamesRandall avatar Mar 27 '19 10:03 JamesRandall

Stumbled upon this myself.

To return file, you need to return it as FileContentResult and handle it in your own response handler so that it doesn't automatically convert to Base64 string.

public Task<IActionResult> CreateResponse<TCommand, TResult>(TCommand command, TResult result)
{
    if (result is FileContentResult fileContentResult)
    {
        IActionResult contentResult = new FileContentResult(fileContentResult.FileContents, fileContentResult.ContentType);
        return Task.FromResult(contentResult);
    }

     return null;
}

There could be other ways, but this one works.

jlocans avatar Oct 16 '20 12:10 jlocans