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!
Here's how I did something similar sometime ago:
On postback (generate data), send back the updated page with the newest data in the gridview.
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.
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”.)
It sounds like you're trying to do too much at once. I suggest posting back to update the gridview then using a redirect to a new, dedicated page (or ashx handler) to download the file. The gridview page should stay visible when you use the content-disposition header in the download page/ashx handler.
Related
The user fills in a form to download a file. The form results load in a new window (target="blank"). The MVC Controller Action returns a FileResult on success or my "SelfClosingPage" view on failure.
The goal behind this is to have the user download the file in a new page, and if any errors occur, the original calling page's url doesn't change (to the /DownloadFile url) and the user remains on the form page, instead of being directed to an error page.
This all works great, except I need to know when the file download is complete because I'd like to 1) hide the "File is downloading, please be patient" message if the download is successful 2) show an error message if the file download failed.
I was using a Cookie to do this and a JS interval to regularly check the cookies value. It either never worked or doesn't work any more (I can never get the cookie to show up on the original page).
Please advice. I can't use C# code in my JS because well, it wouldn't work since it executes once when the page is loaded and I'm trying to decouple the JS from the C# code.
I think my only solution is to do ajax javascript callbacks, but I'd like to avoid that.
UPDATE:
Found these related SO links that use the same approach I was trying to use.
MVC3 - File Download - Wait Status indicator
Detect when browser receives file download
Update 2
It's working again. I think the cookies expiry date was not long enough (though it should have been). I just changed it from 10 min (a file download should not take longer than that) to half a day.
When I start a postback using __doPostBack, a file is created and going back to the user to download in the HttpContext.Current.Response.
Because I change the Response, the page including its javascript values is not modified
But when I have no file to output, the page is refreshed (because of the postback) and the javascript modification on the page are lost.
How can I 'stop' the postback from continuing and persist my current page? I can't use an async postback, because I need the postback to let the user download the file.
EDIT: more info after some questions in the comments:
The file is requested in a webservice request. The webservice needs
to execute a heavy query to determine if a file will be created. I
prefer that this only happens once.
The user can drag / drop some filters that will be used in the file
request. If no file is available, the user should be able to change
his filters, so thats why the page should not be changed.
From the W3 standards and RFC 2616:
10.2.5 204 No Content The server has fulfilled the request but does not need to return an entity-body, and might want to return updated
metainformation. The response MAY include new or updated
metainformation in the form of entity-headers, which if present SHOULD
be associated with the requested variant.
If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view. The 204 response MUST NOT
include a message-body, and thus is always terminated by the first
empty line after the header fields.
Note the bolded line here. I have not tried it myself; however, setting the HTTP status to 204 and sending back an empty document, rather than trying to stop postback entirely, is certainly worth a shot.
Good luck, I hope this helps.
EDIT: this is the code that does the trick:
System.Web.HttpContext.Current.Response.StatusCode = 204;
hii,,
I have a mail list where i can select many mails and download (with/without opening the mail). During the download process i update the mail status(download/open) and show the content in pdf. In normal browser dialog opens where user can save open or cancel options exits.
But if the user cancel then the update process done on the mail should not happen. so i think about doing the update process if the user clicks open or save but how can i identity that client control (i think it depend on the browser)
The issue is present if i download and unopened mail and click cancel button in the dialog box
the pdf creation code i have done is in this link
how to create PDF from HTML stored in a string from database using itextsharp
which i used to open that dialog in browser to save pdf
how can i manage this issue, please suggest efficient method(if possible with code) to handle this issue
There is no way to tell what the user has done once you've sent them the PDF from the server, whether they save the file or cancel is entirely client-side within the browser and you won't be able to get notified of what happened.
Also note that some people have PDFs set to open and display within the browser automatically so they might not even get a dialog at all.
If I understand the problem correctly, then you would have to introduce an additional step before you present the user with the open/save dialogue.
For example: Provide two buttons [open/save] and [cancel]. The first will proceed to show the dialogue and update the mail, whereas the second will not even show the dialogue. If they click open/save and then cancel the dialogue message then it is not your problem.
You could even provide a list with checkboxes for the user to specify which mails he/she would like. (I don't know enough about your process to know if this is valid, but you get the idea.)
I am trying to create a wizard using jquery (fill in a dialog of info, press next, dialog changes but page does not refresh). During this process I would like to upload a file to a document library. I do not wish to reload the page. Is this possible? How would you go about doing this?
You can use uploadify plugin here, which uses a flash component to upload files and it provides events for almost every state of uploading, so you can fire your functions whenever you want for changing content showing alerts etc...
As redsquare says there are also other plugins, but i used this one in a project and it works pretty well.
Hope it helps,
Sinan.
I have a web page which displays some report. When I click on the link for excel, it puts all the data that is displayed on the screen into a CSV file and opens a File Download window which lets me either Open, Save or Cancel.
I want to download this file to a specified location programatically without the user seeing the File Download window. I am using a Windows Application. I dont have the code for the website displaying this report hence dont have the dataset. Also, I looked into the HTML that gets generated by doing a view source on the page but I can't really scrape through it to get the data.
Hence I need to know how to download an excel file from a given website to a location on my computer.
Thanks in advance
Rita
Well you'll need to find the appropriate link or post action. You can then use something like:
string url = "http://whatever/.../foo.xsl";
string target = #"c:/excel documents/foo.xsl";
WebClient client = new WebClient();
client.DownloadFile(url, target);
It gets a bit more complicated if you need to authenticate etc though.
I assume that you're showing the web page within a WebBrowser control. You can handle the WebBrowser.Navigating Event and inspect the value of the WebBrowserNavigatingEventArgs URL property to see if string.EndsWith(".csv", CurrentCultureIgnorecase) (or perhaps a more specific test).
If you detect that the link that has been clicked is for a file you wish to download then you can call e.Cancel() = True on the WebBrowserEventArgs instance to stop the browser from proceeding with its normal behavior of opening the File Download dialog. Then you can use .NET's HttpWebRequest and HttpWebResponse classes to manually download the file.
Here's a sample of downloading using these classes
Actually I am doing a screen scraping, so I am not displaying the web page.
What I have done is gone to the URL where the report is displayed on the screen. There is a hyperlink for 'Excel'. I make this hyperlink click from my program itself. On clicking this link, it opens the File Download dialog box.
I have written, the WebBrowser.Navigating and Navigated events, but the control does not come here. Any ideas
1 more thing, the site that I am accessing is java website.