Execute code after Excel Download in ASP.NET - asp.net

I'm having a piece of code which downloads excel of Invalid records after Import.
I want to refresh a grid after this kind of partial successful import. But, code after excel auto download is not executing.
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=" + PathToExcelFile);
Response.AddHeader("Content-Type", "application/Excel");
Response.AddHeader("Content-Length", file.Length.ToString());
Response.WriteFile(file.FullName);
HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true; // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest();
I had found that Response.Flush() will throw an Thread Abort exception. Hence changed it to CompleteRequest(). But, still no luck.
Not sure what I'm doing wrong?

Save the file name/path etc. to ViewState variables, then call window.open to a separate download.aspx page which processes the downloading of the file. In the Download page reference the ViewState variables you previously set. In the original (not the download) page you can execute what ever code you like after the window.open call.

Related

Avoiding Protected view when opening streamed Excel documents

We have an ASP.NET application which dynamically generates Excel documents and streams them to the client, using Response.WriteFile, see code below. Note that the document is deleted once the file has been written to the client. Thus, no documents are ever left on the server.
However, my client's users has now all upgraded to Office 2010, and now the documents will open in "Protected View". In order to edit the document, the user has to click "Enable editing" first. This is considered unacceptable for the users.
The reason that this happens is that streamed documents are placed in the Temporary Internet files, and this is considered a "potentially unsafe location". And documents in such locations are opened in protected view. I am just hoping there is some way to work around this.
Theoretically, I could place the document in a folder which is accessible from the client, and redirect to the document.
This solution is not an option, however. Firstly, since the document would be left on the server, it could be accessible for other users, which is a problem since the documents may contain confidential data.
There are other reasons why this is not a vialable option.
An other theoretical workaround would be to ask all users to disable the setting "Enable protected view for files located in potentially unsafe locations". Naturally, this is not an option either.
So, in short, is there anyway to avoid the documents to be opened in "Protected view" while using the streaming technique described below?
Response.Buffer = true;
Response.Clear();
Response.AddHeader("Pragma", "no-cache");
Response.Expires = 0;
Response.AddHeader("Content-Type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + proposedFilename);
Response.WriteFile(dstFullPathName);
Response.Flush();
Response.Close();
File.Delete(dstFullPathName);
HttpContext.Current.ApplicationInstance.CompleteRequest();

ASP.NET Response.BinaryWrite throws error in ie when creating Excel file

I have a method that returns a byte array. I then write this array to the output stream as an excel file. Some users are reporting "Internet Explorer was not able to open this internet site" errors in ie7.
I don't get this error when I run it in the test environment (using ie9). However sometimes the first time I click the link, Excel will open but I'll receive an error the reads "there was a problem sending the command to the program" and the file doesn't load into Excel. If I click the link a second time, the file will open in Excel fine. Here's the code that send the byte array through the response stream, after the user clicks a link on a page.
byte[] buffer = GetBinary();
Response.ContentType = "application/vnd.ms-excel";
Response.Buffer = true;
Response.Expires = 0;
Response.AddHeader("Content-Type", "application/vnd.ms-excel");
Response.AddHeader("Content-Length", buffer.Length.ToString());
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.AddHeader("Content-Disposition", "attachment;filename=xx.xls");
Response.BinaryWrite(buffer);
Response.End();
If it makes any difference, the link they click opens up a new window, and the above block of code executes in the page_load event of the new page. What could be causing these errors? I've used similar code before with no issues.

Updating a page before initiating a download?

I've got a page that allows users to enter search criteria and then display matching records. It also has a download button to enable the user to download matching records.
How can I code it so that clicking on "Download" will first refresh the record display before downloading the data?
This is the code that I'm using for the download:
Response.ClearContent();
Response.ClearHeaders();
using (MemoryStream outputStream = new MemoryStream())
{
// some details elided...
outputStream.Write(documentData, 0, documentData.Count());
string fileName = GenerateFileName();
Response.AppendHeader("content-disposition", String.Format("attachment; filename={0}", fileName));
outputStream.Flush();
outputStream.WriteTo(Response.OutputStream);
}
Response.Flush();
Response.Close();
Only one response you can send back to the browser, ether you update the data, ether you send the new header to start the download.
To make both of them you need to change your steps probably using some javascript and/or ajax call.
How HTTP protocol works: http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html
Construct a javascript method that first updates the page via AJAX, then proceeds to make a non-AJAX request to download the file. As Aristos says, this cannot be done in a single request. A different solution could be to download the file first (non-ajax), then refresh the page without ajax. Normally, javascript code cannot be executed correctly after a new non-ajax request is made, but if it only downloads a file, I think the code might continue its execution to post the next request.

Send XML File to client

I have an XDocument object that needs to be downloaded by the client. This xml will be generated on page_load and then sent to the user as a download.
I cant figgure out how to send the object to the client without having an acctual file.
Any ideas?
As stated i checked this other post not quite the same but close enough.
Response.Clear();
Response.ContentType = "text/xml";
Response.AppendHeader("Content-Disposition","attachment;filename=" + DateTime.Now+".xml");
Response.Write(doc.ToString());
Response.End();

IIS7 downloading file length

I've following code for file download:
FileInfo fileInfo = new FileInfo(filePath);
context.Response.Clear();
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.IO.Path.GetFileName(filePath));
context.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
context.Response.WriteFile(filePath);
context.Response.End();
When I run it on my local IIS6 it works fine. Web browser (tested on IE8, Firefox 3.5.2, Opera 10) shows file length before I start download the file.
When I run this code on remote IIS7, web browser doesn't shows file length. File length is unknown.
Why I don't get file length when this code runs under IIS7?
Use Fiddler to check what is actually sent. My guess is you are getting chunked encoding as a result of buffering being set to false on the IIS7 server.
BTW, drop the Response.End call its quite a traumatic thing to do and is unnecessary (for that matter so is the call to Clear).
Edit
Strictly speaking when streaming content with chunked encoding (which is desirable in your scenario) the Content-Length header ought not be present (see RFC2616 Section 4.4.) It seems to me that IIS7 takes it upon itself to enforce this. In fact I've had a Classic-ASP scenario in which IIS7 throws an error when COM code tries to add a Content-Length header when buffering is off.
This is really annoying because despite what the committee in the ivory towers would like, this header give the end user a very useful piece of info.
Thanks for this post.... I got it working for IE with the first line.
public void WriteCSV(string strData) {
//Required for IIs7 WS2008R2 fix
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=report.csv");
Response.Write(strData);
Response.Flush();
Response.End();
}

Resources