-1

Looked far and wide and still cannot find a way to synchronously download generated files from a form POST. I know the process is asynchronous but I want to keep the user waiting OR allow them to download other files while others are downloading.

My page asks the user for a file ID and then generates that file and sends the user the file requested. Either they wait or keep on downloading other files and get a "File save" dialog for each one as they come.

As soon as the user asked for a new file while the last request did not complete downloading, the process is canceled and only the new request is processed (downloaded).

I tried with Ajax (jQuery) but it is not working. I can wait on upload but not on download and plus there is a security issue showing the URL to the file and the file is never saved on the server to begin with.

Any help would be appreciated.

c# code

[HttpPost]
public ActionResult GetFile(int id)
{    
    //code    
    return File(fileData, contentType, originalFileName);
}
stuartd
  • 70,509
  • 14
  • 132
  • 163

2 Answers2

0
public FileResult Download()
{
    byte[] fileBytes = System.IO.File.ReadAllBytes(@"c:\folder\myfile.ext");
    string fileName = "myfile.ext";
    return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

Stolen from here. Download file of any type in Asp.Net MVC using FileResult?

CountZero
  • 6,171
  • 3
  • 46
  • 59
  • Hi, I am doing this, I need a solution for a download completed event on the user side. No Ajax cuz the file is generated on the fly. – Sunday Coder Aug 01 '17 at 16:23
  • It sounds like you are making it harder than it needs to be, just generate a link and let the browser handle the downloading. You should be using a GET rather than a post. What is your use case? – CountZero Aug 01 '17 at 21:55
  • As is files download but I need to show user the progress or simply the fact that the files is on its way, that's it. Not complicated at all but the solution is not obvious because of the async task that is involved here with returning a file as the example you posted. Any way to know if the browser is busy with a GET or POST? May be a adding an js event I don't know of? – Sunday Coder Aug 01 '17 at 22:27
0

I once made a solution like this:

<form ... target="my_iframe">
</form>

<iframe name="my_iframe" style="display:none"></iframe>

The hidden iframe will process the form submit, including waiting for the download to start and then popping up the Save dialog.


Note that if your download can fail - and failure is always an option! - then the output for that failure will also end up in the iframe, and because it is hidden it won't be seen by the user.

I solved this by having the form processing code on the server produce both the File (if it could) and a Cookie that would contain "OK" or "ERROR", and then polling every ~250ms using javascript for that Cookie. In case of "ERROR", I copied some of the iframe contents to an error-div below my form.

Peter B
  • 22,460
  • 5
  • 32
  • 69
  • Hi Peter, I've seen this done, haven't tried but do I need to keep create new iframes for each request so I don't post to the same iframe and cancel last request? How can I use this approach and keep user from requesting another file until download is complete? Cheers, – Sunday Coder Aug 01 '17 at 16:21
  • You could use multiple hidden iframes, either fixed or added dynamically to the page using javascript or jQuery, and rotate the `target` of the `form` accordingly. – Peter B Aug 02 '17 at 07:38
  • How can detect when the iframe finished downloading the file so I can keep a gif animation going and disable the download button? – Sunday Coder Aug 02 '17 at 19:25
  • You can use the cookie, or if you have multiple downloads: generate an ID for each download (submit it using the form) and check if for that ID a response-cookie was received already. – Peter B Aug 03 '17 at 08:55
  • 1
    Solved it with the cookie approach. Works like a charm. Cheers. – Sunday Coder Aug 04 '17 at 01:10