Side actions not happening after Response.WriteFile() - c#

As per an ASP.NET page, on click of a button the following actions should happen:
Download a file from server
Perform clean up actions like
Hide a Button
Set text to a label
Display the label
Disable a button
etc.
Now the download part happens through the following code:
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename="+strFileName+".pdf");
Response.WriteFile(strBrowserPath);
And the remaining actions (Point 2) are done after.
Sadly, since Response.Clear()/Response.WriteFile() is used the remaining server side actions are not happening.
Any alternatives? Any fixes for this?

From the moment you use the post back action to send a file, at the same time you can not send and the page with the changes (disable button, change text, etc). There is no fixes for this because there is not a problem, is the way its works. You have one pipeline to send your response back. You ask for one http response and you get one http response, you can not have both update page and file.
Now, alternative. First of all is how you going to send the file. I suggest to use a handler with parameters like download.ashx?Dhwoload=filea.pdf and after the post back with the update on your page, you call the
window.location = "download.ashx?Dhwoload=filea.pdf";
javascript, with an alternative link as
if the file did not start to download automatically click here
and make your work.
relative:
What is the best way to download file from server
Error handling when downloading file from ASP.NET Web Handler (.ashx)

Related

How to fix Google Chrome loading the page twice when Response.ContentType is 'audio/wav'?

I have a very basic ASP.NET application which writes data downloads from a URL and passes it to the client as an inline audio(.wav) file. This works fine in IE, but in Chrome the Page_Load method is fired twice causing some other issues in the application.
The application works fine in Google Chrome (Page_Load method is only called once) if I pass on the file as an attachment. But when I specify the 'ContentType' as 'audio/wav' as an inline attachment (content-disposition = inline), the event is fired twice.
Interestingly, when I try remove the 'audio/wav' ContentType property but keep the file as an inline attachment, the page works fine and only loads once, displays the content as text on the page. So I am pretty sure the issue has something to do with the MIME type.
Here is the code I am using:
Response.ContentType = "audio/wav";
Response.AddHeader("content-disposition", "inline;");
Response.BinaryWrite(httpClient.GetByteArrayAsync("url").Result);
Response.End();
This code works fine in IE but fires the page twice in Google Chrome. Please suggest a solution. Thank you
It seems when I added this header, it won't run twice. But that is really not what I wanted to do.
Response.AddHeader("Content-Disposition", "attachment;filename=ABC.pdf");

Use indicator for downloading file in mvc

We have a Html.BeginForm(...) with a download button in it. When the button is clicked we enable a busy indicator prior to the submit. The form posts to the controller and the controller returns a FileStreamResult with the response headers like set so the file is downloaded instead of opened or begin redirected.
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=downloaded-file.pdf");
// Return from the controller.
return new FileStreamResult(GetTestFile(), "application/pdf");
I need a way to now disable the busy indicator once the controller returns since there is no redirection.
One solution that i recommend is to detect when browser receives file download
It referenced this link and this link
The ideea is following: it's sends a cookie (C# Generated) with the file (that you are downloading). Use a window.setInterval to query for the presence of a cookie at regular intervals and check its value,and, if you have that cookie you can disable busy indicator.

After disabling a Submit button with JS, re-enable after file download

I'm working on an ASP.NET application. Currently when the user clicks "Save" on an item, we disable the Save button, change its text to "Saving..." and so on. This works fine, because the button causes a postback which results in a new page being loaded, on which the Save button is no longer disabled.
We now want to apply this to other actions: Publish (not much different from Save), Import (again, much like Save, but based on data the user has uploaded in a previous step), Export (downloads an XML file to the user) etc.
Export is causing me problems - the button stays disabled. I think this is because the server sends back an XML file rather than a new web page, and so the browser just displays the same page.
The server-side code is along the lines of
Response.Clear();
Response.BufferOutput = true;
Response.ContentType = "text/xml";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + whatever);
[push file contents into Response.OutputStream]
Response.End();
[No idea if this is good code or not - it's not mine - but it does the job :)]
Basically, I'd like to know either:
a way of making the server send a fresh page back in the response as well as the XML, thus re-enablnig the button in the same manner that the other pages do, or
a way of getting the browser/JS to re-enable the button once the file has been sent.
Looks like this should do it: essentially, set a cookie with the file response, and have the browser waiting for that cookie in order to unblock the page.
The problem probably is that you do not load a new page at all.
Since content disposittion is attachement, the browser will not reload the page but only save the return from the server to disk.
You need to reload the page some how but I have no really good idéa on how to do that after a file fetch.
There is a dirty hack. You can use setTimeOut method to enable and change back button caption/image.
So you can write a server side code similar to
btn.Attributes.Add("onclick", "this.disabled='true'; this.value='Processing...';_doPostback(this,null);setTimeout(function() { enable button logic....set the text /img of the button}, );");
The server side download attachment event will not be synch perfectly, but you can set timeout as 2-5 seconds depending on your server configuration.
Thank you!

Sending ICalendar event to client while still continue running your code

I have built a basic calendar event using DDay.iCal, when I click "Add to calendar" link I produce an event and then sends this to the client.
Basically, my application works like this.
A User logs in.
Selects a specific date.
Books a specific timeslot
Clicks the "Add to calendar" link
Sending the event is done by using Response.Write() which sends the following to the client:
Response.ContentType = "text/calendar";
Response.AddHeader("Content-disposition", "attachment; filename=appointment.ics");
Response.Write(iCalString);
The above works fins but it requires me to first book the event then manually and then click the "Add to calendar" link.
I want to merge the steps 3 and 4. But when trying to do so the event booking gets saved to the database but the screen does not get refreshed.
Is there a "simple" way to get around this?
You need to set up a simple HttpHandler to post the reply and then do a Response.Redirect() into it.
I have done similar work before with integrating the vcard format into an our people section of a website. These articles should tell you everything you need to set up the HttpHandler - just replace the vcard code with your ical code.
http://professionalaspnet.com/archive/2007/09/23/Streaming-a-vCard-on-the-Fly-in-ASP.NET-with-a-Custom-httpHandler.aspx
http://weblogs.asp.net/gunnarpeipman/archive/2009/08/09/creating-vcard-with-image-in-net.aspx
When you redirect into the ical handler it will just instantly pop up the download box, you wont be taken to an empty page, the user is left on the same page.
Make sure that you clear your response (Response.Clear) prior to sending the iCal response information. Finally, end your response (Response.End) before any other content can be emitted. From the end use standpoint this will produce the same result of using an HttpHandler without the hassle.

IE Information Bar, download file...how do I code for this?

I have a web page (asp.net) that compiles a package then redirects the user to the download file via javascript (window.location = ....). This is accompanied by a hard link on the page in case the redirect doesn't work - emulating the download process on many popular sites. When the IE information bar appears at the top due to restricted security settings, and a user clicks on it to download the file, it redirects the user to the page, not the download file, which refreshes the page and removes the hard link.
What is the information bar doing here? Shouldn't it send the user to the location of the redirect? Am I setting something wrong in the headers of the download response, or doing something else wrong to send the file in the first place?
C# Code:
m_context.Response.Buffer = false;
m_context.Response.ContentType = "application/zip";
m_context.Response.AddHeader("Content-Length", fs.Length.ToString());
m_context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}_{1}.zip", downloadPrefix, DateTime.Now.ToString("yyyy-MM-dd_HH-mm")));
//send the file
When a user agrees to download a file using the IE Information Bar, IE reloads the current page, not the page the file the user is trying to download. The difference is that, once the page is reloaded, IE will allow the download script to go through without prompting the user. I'm not sure what the thinking is on this from a design standpoint, but that's how it seems work.

Categories