I'm working on a SharePoint 2013 site and I've added the ability to save pages in PDF. The PDF conversion is handled by the third party library SelectPdf.
I managed to get everything to work (rendering and file download), except that the "PDF Download" button that I have on my page works only 1 time. Meaning, the click event on the code behind is fired only once, no matter how many times I click the button (notice that I click it with intervals of 10+ seconds). If I want to download the PDF file again, I have to refresh the page.
I put together a "hello world" example (see below) in order to pinpoint the problem:
protected void lnkPdfDownload_Click(object sender, EventArgs e)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
/************************************ Create PDF File ************************************/
string html = #"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">
<html dir=""ltr"" lang=""en-US"">
<body><h1>Hello World</h1></body>
</html>";
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertHtmlString(html);
byte[] bytes = doc.Save();
Response.OutputStream.Write(bytes, 0, bytes.Length); // ALTERNATIVE: doc.Save(Response.OutputStream);
/************************************ Create PDF File ************************************/
//Response.End(); // This throw a ThreadAbortException, therefore I'm using the alternative code below
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
At the beginning I thought it was Response.End() that caused the issue (by throwing the ThreadAbortException), but I replaced it with other code and I still have the same problem (no exceptions are thrown now).
I don't think the problem is in the SelectPdf library: I can comment out the entire block (between the "Create PDF File" comments), and I still get the same thing (obviously no PDF is generated).
I noticed that, at most, I can successfully click the "download" button up to 2 times (it's rare, and not consistent): the third time nothing happens.
While this isn't a huge deal, I think there is something wrong going on that I'm not seeing. Here is why: after I click the "download" button (and get my PDF file), I am not able to go on edit mode in my SharePoint page. The "loading" message keeps spinning but nothing happens (again, unless I refresh the page).
Has anyone had this problem? I looked online but I couldn't find anything about it.
I'm using Internet Explorer 11 and Chrome 51. Please let me know if you need more information. Thank you.
Are you sure there are not javascript/jquery errors happening when the download button is clicked that prevent the re-clicking of the PDF button and also going into edit mode?
Especially since refreshing the page makes everything work again.
Related
I have some asp.net application, which contains 3 rdlc reports. I open those reports in report viewer and it works great. I can download report as pdf file, and also print it from report viewer. Now what I would like to do is this (only if using mozzilla browser): I want to show only pdf file of the report in browser, actually in mozzila pdf viewer. here is the link as an example: http://www.selab.isti.cnr.it/ws-mate/example.pdf (open it in mozzila).
And also i would like to know if this could be done with javascript. Just to mention, i open this reports on button click.
Hope I was clear enough with my question, if you need some more info let me know.
Not javascript but here's how I would do it. For simplicity I'm assuming the report is already loaded into the reportviewer.
In your button click event handler:
//perform check for mozilla... see http://msdn.microsoft.com/library/3yekbd5b
if (browser.Name == mozilla)
{
//get report from viewer
byte[] bytes = ReportViewer1.LocalReport.Render("PDF");
//display pdf in browser
Response.AddHeader("Content-Disposition", "inline; filename=MyReport.pdf");
Response.ContentType = "application/pdf";
Response.BinaryWrite(bytes);
Response.End();
}
Let me know if I missed something but I think understood what you wanted.
I'm working in ASP.NET (2.0) and we have a page where a user is able to select and download a series of files as a zip. I got this to work without undo difficulty by using the DotNetZip library (which is probably not relevant to the problem, but included for completeness.)
After the user checks which files they want to download, the page does a postback, and in the button click event handler, I use the following code:
Response.Clear();
Response.BufferOutput = false; // false = stream immediately
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "filename=FileRequest.zip");
using (ZipFile zip = new ZipFile())
{
zip.AddFile(MapPath("/datafiles/fileToZip.pdf"), "");
zip.Save(Response.OutputStream);
}
Response.Close();
And this all seems to work great. The user clicks the button, a download window pops up, the user downloads the zip. All is good...
...until they decide they want to do something else on the page. The buttons in the form are no longer responsive. For instance, if I click the download button again, it does nothing. If I reload the page, I can repeat this behavior...it works once, then does nothing.
I'm not understanding why the browser doesn't send the new request. It's not "spinning" or otherwise acting busy. I thought that this might be a browser issue, but I've repeated it in both IE and Firefox, so it seems likely that it's something I'm not understanding. Strangely, it's only form submission elements that seem to be non-responsive. Javascript still works, and so do regular links.
So why is this happening, and how do I get around it?
The problem is likely down to you returning;
Response.ContentType = "application/zip";
Once this has been sent (along with the actual content), the browser would assume it has nothing left to do (I believe).
You probably should create a new window specifically for downloading the files by saving the file selection in a session parameter (or equivalent) and opening a popup window that has your download code in.
This will leave the parent page in a suitable state.
Content-disposition header seems to be a discouraged solution. But the same effect of ASP.NET forms not being responsive occurs if you use standard Redirect to a zip file.
I solved very similar problem (returning *.csv files by the server for download) using Tančev Saša's code in "Response.Redirect to new window" Q&A and it works great. Perhaps it might produce some popup warnings in some browsers, but I think this is how it's often done in download sites.
I know this kind of question has been asked many times.
Yet I don't succeed in displaying an image from my db on a page.
I tried the following method.
protected void Page_Load(object sender, EventArgs e)
{
//Get the picture id by url
//Query here
byte[] picture = queryoutput;
Response.ContentType = "image/jpeg";
Response.BinaryWrite(picture);
}
Link to get the image.
<asp:Image runat="server" ImageUrl="~/givememypicture.aspx?pic=3" ID="testimage" />
The <asp:Image /> tag is located in between <asp:Content > tags.
When I run this code and check in firebug, it simply states 'Failed to load fiven URL'.
I also tried putting the Respone.Con...(picture); part into a public method and call that method with the byte var given.
I'm quite new to asp.net, but I have somewhat more experience in c#.
I start to really dislike asp.net... I have been struggling with this for about 20 hours already and tried a lot of options, yet none worked.
The best would be if I could just fill in the picture via the codefile from that same page. It seems quite illogical to me to call another page to load the image from.
Can somebody please tell me what I'm doing wrong here?
Solution: Master page reference removed from the page directive on the page that handles the image response. Also removed everything else except for the #page directive itself within the aspx file.
try using a handler file (.ashx) put the code form your page_load in that lie so
public void ProcessRequest (HttpContext context) {
//Get the picture id by url
//Query here
byte[] picture = queryoutput;
Response.ContentType = "images/jpeg";
Response.BinaryWrite(picture);
}
public bool IsReusable {
get {
return false;
}
}
then call the handler file and pass the correct querystring items from the
this should then work
There's an error in your path reference...
ImageUrl="/~givememypicture.aspx?pic=3"
should be:
ImageUrl="~/givememypicture.aspx?pic=3"
~ is shorthand for "the application root" and needs to be followed by a slash to indicate that it's a directory. Think of it as similar to other path shorthand notations such as . and ...
Make sure you call Response.Flush(); and also Response.End(); and see if that does the trick
Also, your content type has a misspelling. Is not "images/jpgeg" I think it's "image/jpeg"
EDIT: Yes, I just confirmed in Wikipedia that the correct content-type is image/jpeg.
I do this all the time. Here's some sample code:
Response.ContentType = "image/jpeg";
Response.BinaryWrite(bytes);
That's all there is too it. If it's not working, then something is probably wrong with your data.
A flush is not required. I have working code for this open on my screen right now.
I would suggest that you try writing that buffer of data to a file and see if it opens up as a valid picture. I bet something's wrong with that data.
Also, it's a good idea to enable browser side caching for your dynamic content. Here's a GREAT link that shows exactly how to do that, which will boost your performance / scalability a lot.
http://edn.embarcadero.com/article/38123
I need to send an image (as a downloadable file) from an ASP web page. It is working correctly in every browser except for IE (all versions).
Here is the server side code:
bool export = Request.QueryString["Export"] != null;
if (export)
{
byte[] allBytes = File.ReadAllBytes(#"C:\MyImage.tif");
Response.ContentType = "image/tiff";
Response.AddHeader("content-disposition", "attachment; filename=\"MyImage.tif\"");
Response.OutputStream.Write(allBytes, 0, allBytes.Length);
Response.OutputStream.Flush();
Response.End();
return;
}
And here is the JavaScript:
$('#ExportFrame').attr('src', 'Default.aspx?Export=true'); // ExportFrame is an iframe
In IE, I keep getting an error saying "Internet Explorer cannot download Default.aspx from localhost". I thought it might be an issue with loading it in an iframe element, but redirecting to the URL is not working either. The really odd thing is that going to the URL (/Default.aspx?Export=true) does not work the first time, but works every time after that. Again, this works in every browser I've tried except IE.
Any ideas?
Update:
The aspx page has the following code to keep the page from getting cached:
// Never cache this page
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Response.Expires = -1;
Removing the first 2 lines and leaving only Response.Expires = -1 resolved the issue.
AFAIK, you have to fix the file type association on the client for this to work. Known issue - Windows Updates often breaks this association resulting in this type of error message.
http://www.eggheadcafe.com/software/aspnet/36147698/office-updates-break-tiff-file-associations.aspx
UPDATE
1.) Create a blank text document on your desktop. (File.txt)
2.) Change the file extension from .txt to .tiff.
3.) Right click on the .tiff file and select open. On the next box choose “select program from a list of installed programs.
4.) Click on the browse button and browse to “C:\Program Files\Common Files\Microsoft Shared\MODI\12.0”.
5.) Select “MSPVIEW.EXE” and click “Open”.
6.) Select “Microsoft Office Document Imaging” and click OK.
7.) You will get a message saying it is unable to open the document. That is because it is not an actual graphic image. We are just setting the file association at this point.
8.) Repeat steps 1 – 7 and use .tif as apposed to .tiff because there are two different file extensions for this type of document.
The aspx page had the following code to keep the page from getting cached:
// Never cache this page
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Response.Expires = -1;
Removing the first 2 lines and leaving only Response.Expires = -1 resolved the issue. For some reason this was preventing the image from working properly in IE.
After submitting a form, the user is presented with a link to a pdf document.
The link is straight to the document, it is not streamed.
If the user right-clicks and chooses 'save link as,' the document saves and opens fine. However, if the user just clicks on the link, the browser takes a very long time to respond (I'm going to guess it's 3 minutes) and then adobe reader gives the following error:
"the file is damaged and could not be repaired"
This is in Chrome v5, ASP.NET 3.5 and the link is returned inside an UpdatePanel.
it depends on browser settings that are configured for PDF Links. If you change the settings in broweser, you will get the download dialog.
Mozilla Firefox
Open Mozilla Firefox
Click Tools and then Options
Within the Options window click Applications
Select the Content Type you wish to adjust. For example, if you want to change how a .PDF file opens in Firefox, select Adobe Acrobat Document.
In the Action section, change the action to how you wish to open the file. If you want to download .PDF files instead of opening them, select Save file.
Internet Explorer:
You have to right click and click save target as to download.
The other option is, create a seperate asp.net and write below code to download the PDF
private void Page_Load(object sender, System.EventArgs e)
{
//Set the appropriate ContentType.
Response.ContentType = "Application/pdf";
//Get the physical path to the file.
string FilePath = MapPath("acrobat.pdf");
//Write the file directly to the HTTP content output stream.
Response.WriteFile(FilePath);
Response.End();
}
I've had this issue before and the cause was the PDF itself.
Adobe has a slew of causes for this: http://kb2.adobe.com/cps/328/328233.html
FWIW, my PDf issue was solved by opening the PDF in Adobe and going to Document -> Reduce File Size -> Make Compatible with Version 7. (current version - 2)