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.
Related
I have a webpage that I want to monitor that has stock market information that I want to read and store. The information gathered is to be stored somewhere, say a .csv file or similar for later analysis.
The first problem I have is detecting when this page has fully loaded. The time taken to load can vary enormously. The event handlers I have tried all fire multiple times (I know this has been covered and I have tried the various techniques, but to no avail). Perhaps it is something specific to do with this web-page? Anyway, I need to know when this page has fully loaded and is sitting pretty with all graphics displayed properly.
The second problem is that, I cannot get the true source page into the webbrowser. As as a consequence, all access to the DOM fails as the HTML representation inside the webbrowser control appears not match what is actually happening on the webpage. I have dumped the text (webBrowser2.DocumentText) and it looks nothing like what you see when I check source in a browser, chrome for example. (I also use the firebug extension in Firefox to double check things). How can I get to the correct page into the webbrowser so I can start to manipulate things?
Essentially, in terms of the data, I need the GMT Time, Strike Rate and expiration time. My process will monitor with a timer control. To be able to read all the other element data on screen is a nice-to-have.
Can this be done?
I am an experienced programmer new to web programming and C#.
I think you want this AJAX request.
As a review, the web works by first loading the web page, then scanning the web page for additional files it needs to load (js, css, images, etc). When those finish, the onload event is triggered and some AJAX functions may run.
In this case, only some of the page is loaded and AJAX functions update the data in the graph later. As you've seen "Show Source" only shows the original file that was downloaded and is not a dump of its current state.
The easiest way to get the data is to find the URL of the AJAX request that loads the graph data. It is already conveniently formatted in JSON for you to scrap.
On a website, I'm successfully using an ASHX handler to download files from the server to visitors of my website.
A customer suggested to not rely on the browser UI to visualize the download progress but instead provide some progress on the page to provide a more visual cue.
I.e. first, the user sees a download page with a link/button:
Then, when clicking the Download your file now! button something like this should appear:
Unfortunately, even after searching Google and SO for hours, I found zero similar topics. All occurrences deal with upload, not download. Either I'm using the wrong keywords or there are really no solutions.
Therefore my question:
(How) would it be possible to provide such a download progress?
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;
Ok, I've done my homework and have found similar threads. However, I haven't found a good answer.
Using MVC3, C#, Razor View Engine.
My scenario is pretty straightforward. I have a view with a link that calls an action on a controller. That action returns a file that was dynamically generated. The process takes anywhere from 1 to 10 seconds. During this time I want to lock the UI and display a "Please Waite" message.
My first attempt used something like this:
#Ajax.ActionLink("my test link", "myAction", new { Controller = "myController" }, new AjaxOptions { OnBegin = "ajaxStart", OnComplete = "ajaxStop" })
The ajaxStart and ajaxStop functions then used the jquery blockUI script to block and unblock the UI and display the "Please Wait" message. This worked in that it showed the message, but no file would download. After some more research, I found that I could not use Ajax to initiate a file download. If I'm wrong, please enlighten me.
So, I'm back to a normal ActionLink. This works in that I can download a file. I can even catch the .click event and block the UI and show the wait message. However, how do I know when to unblock the UI? How can I know when the file save/open dialog has opened up? Perhaps if I could catch that event I could then unblock the UI.
I have seen the other posts that recommend a much more complex solution by breaking the file generation/download into separate functionality. I very much want to avoid having to save the file on the server, or having to poll the server to see if the file is done yet. This should be fairly simple.
If anyone has any ideas, please let me know.
Thanks,
Tony
there was a post awhile back on this on SO:
Detect when browser receives file download
It referenced this link: http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx
Effectively what it does is it sends a cookie (C# Generated) with the file (that the user is downloading) to the client. Once the client has the cookie, theoretically this happens after the file is downloaded). Javascript will check to see if the client has that cookie, if so Javascript will unblock the UI.
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.