Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start a file download after a Postback

In my application I am building a zip file for the User to download for some exported database information. The zip file is created when the user clicks a "generate data" button and I log the request in the database.

On my page, I have a Gridview which shows the download history of the User and also offers them the ability to download the latest generated file for a set period of time.

The issue I'm having is when they click the button, I'd like the page to refresh (thus refreshing the gridview and showing their latest request) and then start the file download for them (IE, bring up the prompt and let them decide whether to open/save/cancel it).

I'm able to start the download on a post back, but my Gridview is not updating before it begins so it doesn't show the newest request in the list. How can I get the gridview to update BEFORE the download prompt starts?

I'm using the following to start the download:

    public void BeginDownload()
    {
        FileDownload download = InventoryService.GetLastThreeFileDownloads(this.EmployeeId).First();
        FileInfo fi = new FileInfo(Server.MapPath(SERVER_DOWNLOAD_PATH) + download.DownloadFileName);

        Response.Clear();
        Response.ContentType = "application/zip";
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + fi.Name);
        Response.TransmitFile(fi.FullName);
        Response.Flush();
    }

The method is called in the Page_Load event as the last item, if a hidden field is set to true (which I set when they click the button to build the file).

I've also tried doing this through jQuery / AJAX calls to either refresh the page and start the download with little success. I have thought about opening a modal dialog and letting them click a link to start the download and then refresh the page when the modal closes, but that's a last resort if I can't find another solution.

Any help is greatly appreciated!

like image 753
Delebrin Avatar asked Feb 07 '11 20:02

Delebrin


2 Answers

Here's how I did something similar sometime ago:

  1. On postback (generate data), send back the updated page with the newest data in the gridview.
  2. Add a small javascript function which executes when the page completed loading and which requests the generated file (something like window.location='fileurl';. Of course only send this javascript function on postback.

The content of the displayed page does not change when requesting a file, it will simply pop up the save dialog of your browser.

like image 128
marapet Avatar answered Oct 19 '22 00:10

marapet


The thing is you do not send the page back to the user. The user clicks the button, which sends an HTTP request, for which you generate a HTTP response containing the file to be downloaded. If you would like to refresh the page and only after that send him the file to be downloaded, you need to send a normal postback result (not calling the BeginDownload method), and then somehow force him to do another request, upon which you respond with the file.

There are various options here:

  • include meta refresh tag on the page
  • use an onload JavaScript
  • use an iframe
  • …or have the user click a link, as you said.

All methods have their downsides (be careful especially about IE’s “unwanted download” protection, which, under some circumstances, can be annoying), you should probably at least include a download link with “if the download does not start automatically, click here”.)

like image 2
Mormegil Avatar answered Oct 18 '22 22:10

Mormegil