I'm trying to have a user click a button on a web page to download a CSV file, but I'm having problems sending the correct data to the user. In addition, once the file has been downloaded, I'd like the page to remain "active" i.e. the page can continue to trigger events to the server, such as clicking the Download button again.
This is the code I'm currently using, pieced together from various SO questions:
var sb = new StringBuilder();
string fileName = "data.csv";
// Build CSV file...
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("filename={0}", fileName));
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.Write(sb.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
This works so far as presenting the user with an option to open or download the file, but the file also contains the entire markup of the aspx file after the requested data, and the page is left completely inactive.
I'm guessing the problem is with the last two lines of the above code. I've tried using ApplicationInstance.CompleteRequest instead of Response.End, but this doesn't seem to change the outcome. The page is still inactive and the file still has the markup at the end. Can anyone help?
In case it makes any difference in the behaviour of Response, the page is an WebPartPage in SharePoint 2010.
Set the line
HttpContext.Current.Response.AddHeader("content-disposition", "filename={0}", fileName));
to
HttpContext.Current.Response.AppendHeader("content-disposition", String.Format("attachment;filename={0}", fileName));
And set the following property on your button
downloadButton.OnClientClick = "_spFormOnSubmitCalled = false;";
_spFormOnSubmitCalled is a javascript variable that SharePoint uses to stop multiple form submits and it is being set to true when you click the download button.
try this
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
HttpContext.Current.Response.ContentType = "application/CSV";
This question already has answers here:
(HTML) Download a PDF file instead of opening them in browser when clicked
(16 answers)
Closed 9 years ago.
Is there a sample way for the user to download, save the PDF file I have on my webpage?
Currently I have:
<tr><td><img src="../../images/speakernotes.png"/>
which just opens the file and does not save it. Looking for a easy way to do this. Thanks in advance.
If you are using HTML5 you can use the download attribute. Here is an example by Google.
Another example.
Yes, you can use the content-disposition header which will force the Save As.. dialog to the user.
So on your image, you can link to say a handler which will serve the PDF, or perhaps do a postback in an ImageButton and then serve the file.
String FileName = "FileName.pdf";
String FilePath = Server.MapPath("~/yourPath");
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
I have a method in my C# codebehind that connects to SQL and creates a CSV file based upon the SQL data. This method is called when the user clicks a particular button on the website. I am trying to get this same method to also prompt the user to "open" or "save as" after the CSV file is generated.
I have tried the following:
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=" + "C:\\temp\\report.csv" + ";");
Response.TransmitFile("C:\\temp\\report.csv");
The user does get prompted to "open or save as". In either case, the data in the CSV file also contains the entire source code of my Default.aspx. What do I need to do to my code to prevent that extra data from being appended onto my CSV? TIA...
You can call response.End() to prevent further processing by your page.
You need to clear the Response first - Response.Clear();
response.Clear();
...
response.AddHeader("Content-Disposition", "attachment; filename=" + "C:\\temp\\report.csv" + ";");
Response.TransmitFile("C:\\temp\\report.csv");
After downloading a file from a webpage, I can't do anything on that page. It is like the page is not working anymore. When I click on other button, there is no post back.
Here are my codings.
filename= "test.txt"
Response.AppendHeader("content-disposition", "attachment; filename= " + fileName);
Response.WriteFile(Server.MapPath("~/" + fileName));
Response.End();
So I try to comment Response.End() but it is still not working.
What can be the possible problems?
UPDATE
Go to this link to see how I solved it.
EDIT 2
It appears that moving the object tag in the Dom is the cause of the problem. I added an iframe directly to the page and it works fine without any problems.
However, when I move that iFrame into a modal dialogue box (http://www.ericmmartin.com/projects/simplemodal/) the PDF disappears (the object tag no longer renders correctly).
So it appears that it's no longer a question about my handler, but more a question about why moving the "object" (or embed) tag in the DOM (which lives inside an iFrame) causes it to "blank-out."
Also, when the pdf is moved from the modal dialogue back to its original position, it appears correctly. So, perhaps I should focus more on the modal dialogue itself.
Thoughts? Thanks for your suggestions thus far.
EDIT 1
So I've made some modifications for testing.
I've got the iframe to output an object tag for pdf requests along with the server time.
Response.AddHeader("content-type", "text/html");
WebClient client = new WebClient();
Response.Write("<html><head></head><body><h1>"+ DateTime.Now.ToString() + "</h1><object height='100%' width='100%' name='plugin' data='" + Request.Url.ToString() + "&embed=true' type='application/pdf' /></body></html>");
Response.Flush();
Response.Close();
Response.End();
Now I get a page with the current time correctly, but the object only displays the PDF the first time after I publish the aspx page. So it appears to be some sort of caching issue? Except that the object isn't loading anything (not even the previously loaded PDF).
If right click on the iframe and refresh the page, the object loads up fine. (The same is true if I use an embed tag).
Original Question
I know there are a lot of questions on this...
streaming PDF data through an ASPX page
Server generated PDF not displaying in IFrame on aspx page on some (but not all )PCs
Displaying a PDF Document in ASP.net page
But they either weren't answered, or the answer didn't work.
Environment
.Net 4
Adobe 9.3.4
IIS 5.1
XP sp3
VS 2010
IE 8.0.6001.18702
Background
The pdf's I'm streaming come from a storage repository where the files don't have any extensions (this is done for security). I look up the file in the database and stream it back to the client via the following code:
Response.Clear();
WebClient client = new WebClient();
Byte[] buffer = client.DownloadData(sPath);
Response.AddHeader("content-length", buffer.Length.ToString());
Response.AddHeader("content-disposition", "inline;filename=" + fileName);
Response.AddHeader("expires", "0");
Response.AddHeader("Content-Type", "application/pdf"); //this is usually dynamic to support other types (doc, xls, txt, etc.)
Response.OutputStream.Write(buffer, 0, buffer.Length);
Response.Flush();
Response.Close();
Response.End();
This works for every file type (doc, txt, xls, html) when used directly in the browser or in the iframe (displayed as a modal popup) with the exception of pdf files. They do not work reliably when accessed via the iframe, but work fine when accessed directly in the browser.
The only time it does work is the first time I request a document after I publish the aspx page that is serving these files. All subsequent hits return a blank page (even from new tabs or browser windows). Firefox reliably displays the pdf every time regardless.
Attempted Solutions
I've tried various ways I of streaming the file:
Response.TransmitFile(sPath);
Response.WriteFile(sPath);
//As well as some others
I've tried adding .pdf to a parameter at the end of the request
http://www.myurl.aspx?File=test.pdf
I've tried making the URL unique by adding a time stamp
http://www.myurl.aspx?File=test.pdf&Unique=Friday__September_17__2010_12_02_16_PM
Un-Attempted
I've read about IIS compression causing problems, but it was for a newer version of IIS.
Didn't try using embed tag since I would like to stick to the iFrame if possible (The existing infrastructure uses it).
Any help would be greatly appreciated!!!
Thanks.
I had a similar problem that arose when the PDFs were streaming over SSL (IE only, FF didn't exhibit the issue) that was only solved by doing the following:
Response.ClearHeaders();
Response.ClearContent();
Response.Buffer = true;
Response.AppendHeader("Content-Disposition", "inline; attachment; filename=Filename.pdf");
Response.ContentType = "application/pdf";
Response.WriteFile(path);
Response.Flush();
Response.End();
So I gave up and decided to use a standard IE popup window instead.
window.open(URL, 'Window', 'height=' + pageHeight + ',width=' + pageWidth + ',top=0,left=0,resizable');
I had to render the pdfs in an object tag and everything else inside an iframe within the popup for it to work, but it works...
if (sDocType == "pdf")
{
Response.AddHeader("content-type", "text/html");
WebClient client = new WebClient();
Response.Write("<html style='margin:0px;padding:0px;'><head></head><body style='margin:0px;padding:0px;'><object height='100%' width='100%' name='plugin' data='" + Request.Url.ToString() + "&embed=true' type='" + zGetContentType(HttpContext.Current.Request.QueryString["docType"]) + "'><param name='src' value='" + Request.Url.ToString() + "&embed=true' />alt : <a href='" + Request.Url.ToString() + "&embed=true'>View</a></object></body></html>");
Response.Flush();
Response.Close();
Response.End();
}
else
{
Response.AddHeader("content-type", "text/html");
WebClient client = new WebClient();
Response.Write("<html style='margin:0px;padding:0px;'><head></head><body style='margin:0px;padding:0px;'><iframe frameborder='0' scrolling='no' height='100%' width='100%' src='" + Request.Url.ToString() + "&embed=true' /></body></html>");
Response.Flush();
Response.Close();
Response.End();
}
I'm not sure that you need to set the filename, especially if it doesn't have the .pdf extension. When streaming PDFs to browser in the past, I've always used this code:
Response.Clear();
Response.ContentType = "application/pdf";
Response.BinaryWrite(pdfBuffer);
Response.Flush();
Otherwise, there's a possibility that something has hosed over the registry settings for the application/pdf CLSID on the client computer.
I was able to solve a similar problem (pdf inside of modal window internet explorer)
by taking out the iframe. Instead, load the pdf into an html object element.
see the link below:
http://intranation.com/test-cases/object-vs-iframe/
To sum it up:
The setup that did not work:
jQuery floatbox, loads html fragment with iframe, load aspx page into iframe, load pdf into aspx page
The setup that now works:
jQuery floatbox, loads html fragment, append object element.
before appending the object element, set data
attribute of object element to the aspx page url