4 ways to send a PDF file to the IE Client in ASP.NET 2.0


In this pick, I am sharing a project using which you can send PDF files to the IE Client in four different ways. You may download the project by clicking here.


Create a new C# Website. While creating the following pages ensure that you DON’T have “Place code in Seperate file” checkbox as checked. You need to create 4 pages called “Way1.aspx”, “Way2.aspx”, “Way3.aspx” and “PDFContainer.aspx” without a code behind.


So the four different ways which I was talking about is as follows…


1) You hit a button on a page and the page refreshes itself with a PDF file in the same instance of the IE Browser. You are not prompted to Open/Save/Cancel by the IE Client at all. The code for this page is as follows


Way1.aspx


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<script runat=”server”>
    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.ContentType = “application/pdf”;
        Response.Clear();
        Response.TransmitFile(“UML.pdf”);
        Response.End();
    }
</script>
<html xmlns=”
http://www.w3.org/1999/xhtml” >
<head runat=”server”>
    <title>Way 1</title>
</head>
<body>
    <form id=”form1″ runat=”server”>
    <div>
        <asp:Button ID=”Button1″ runat=”server” OnClick=”Button1_Click” Text=”Send PDF” /><br />
        <br />
        This page will refresh itself with a PDF file opened in the same instance of IE itself.
        Users will not get prompted to Save/Open/Cancel the PDF file.</div>
    </form>
</body>
</html>


2) You hit a button on a page and the page throws a Dialogbox saying Open/Save/Cancel. You click on Save and the FileName is populated is the document is according to your taste (meaning you have to supply it explicitly).


3) Verify similar to 2 above, but the filename in the Dialogbox is the name of the Page (meaning, if you don’t the supply name, the Dialogbox takes the name of the aspx file as the PDF file name).


The code for this page is as follows…


Way2.aspx


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<script runat=”server”>
    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.ClearHeaders();
        Response.ContentType = “application/pdf”;
        Response.Clear();
        Response.AppendHeader(“Content-Disposition”, “attachment;Filename=UML.pdf”);
        Response.TransmitFile(“UML.pdf”);
        Response.End();
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        Response.ClearHeaders();
        Response.ContentType = “application/pdf”;
        Response.Clear();
        Response.AppendHeader(“Content-Disposition”, “attachment”);
        Response.TransmitFile(“UML.pdf”);
        Response.End();
    }
    </script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
    <title>Way 2</title>
</head>
<body>
    <form id=”form1″ runat=”server”>
    <div>
        <asp:Button ID=”Button1″ runat=”server” OnClick=”Button1_Click” Text=”Send PDF” /><br /><br />
        This button will do a postback and the Client will be prompted with a Dialog Box to Save/Open/Cancel the PDF file transmission. The thing to be noticed here is that the FileName in the Dialogbox will be automatically set as UML.pdf <br /><br />
        <asp:Button ID=”Button2″ runat=”server” OnClick=”Button2_Click” Text=”Send PDF without FileName” /><br /><br />
        This button will do a postback and the Client will be prompted with a Dialog Box to Save/Open/Cancel the PDF file transmission. The thing to be noticed here is that the FileName in the Dialogbox (Way2.pdf) is set as the Page Name, which is Way2.aspx</div>
    </form>
</body>
</html>


4) You hit a button on a page and the page opens a new instance of Internet Explorer and loads the PDF file in the IE Client itself without prompting to Open/Save/Cancel. The code for these pages Way3.aspx & PDFContainer.aspx are as follows…


Way3.aspx


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<script  language=vbscript>
sub OpenInNewWindow()
    window.open(“PDFContainer.aspx”)
end sub
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
    <title>Way 3</title>
</head>
<body>
    <form id=”form1″ runat=”server”>
    <div>
        <input type=button OnClick=”OpenInNewWindow()”  value=”Open in New Window”/>
        <br /><br />
        This time, we will open a new Internet Explorer Window and Show the PDF File directly in the IE
    </div>
    </form>
</body>
</html>


PDFContainer.aspx


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<script runat=”server”>
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.ContentType = “application/pdf”;
        Response.Clear();
        Response.TransmitFile(“C:\\umlclass.pdf”);
        Response.End();       
    }
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
    <title>PDF File</title>
</head>
<body>
    <form id=”form1″ runat=”server”>
    <div>   
    </div>
    </form>
</body>
</html>


UPDATE:By the way, I just found out… these ways will not work with Adobe Reader 6.0 or below. We upgraded to Adobe Reader 7.0 and everything works as expected.


Hope that helps!

-Rahul Soni

SendPDF.zip

Comments (42)

  1. Trackback from dotnetkicks.com

  2. Is there any way to write a pdf from an HTML string rendered in the code behind without using a third component like ITextsharp??

    Regards

    Bhaskar

  3. Hy.I am using VB.NET.I have a little problem.I want to show a pdf on a new page, using JavaScript (Window.Open(url…)).In my page i write in codebehind:

    With Response

                   .ClearContent()

                   .ClearHeaders()

                   .ContentType= "application/pdf"                .Buffer = True

                   .BinaryWrite(myStream)

                   .End()

               End With

    where myStream is a stream of bytes (array of byte) I am sure that my stream is ok… but i don’t see anything unless I use other types of files (jpeg for example).But with pdf is not working

  4. shalini says:

    HI

    i want the same application to do in vb.net but in windows application.

    can u plz help me how to do that

    Regards

    shalini

  5. Paul Marangoni says:

    I am getting an error after downloading a pdf file using this method (with transmitfile).

    "There was an error opening this document. The file is damaged and could not be repaired"

    When I view the file in notepad, I see that there is a bunch of HTML from the web page appeneded. Shouldn’t Response.End() prevent this?

  6. rahulso says:

    Yes Paul, Response.End should take care of this. Can you tell me which way among the 4 you used and what version of Adobe Reader and Operating System you are using?

    Does it happen with all the PDF files, or the ones which are greater than specific size?

  7. Krshna says:

    I am trying to transmit a zip file using the Response.Transmitfile method. Its sending the file and also appending the aspx page’s html to it. Am I missing anything here? Below is the code I am using

    Response.ContentType = "application/x-zip-compressed"

    Response.AddHeader("Content-Disposition", "attachment;filename=" + sFileName)

    Response.TransmitFile("C:test.zip")

    I even tried using octet-stream instead of x-zip-compressed. I checked the IIS Server’s mime-type and x-zip-compressed has been mapped to .zip file.

    If I use Response.End then I don’t get Open/Save dialog window. Technique used to display is

    Search.aspx – To search files to be downloaded

    Results.aspx – displays matched files with a check box against each of them. At the bottom of the page I have a button "Download checked File". On clicking this button, the button click event triggers the download code

    Regards

    Krish

  8. Mark Burns says:

    I am getting the error "Not a valid Virtual Path". My path is "http://www.mysite.com/pdfs/12345ab.pdf&quot;.

    I had been trying to stream the file in ASP.net 2.0 which does not work in IE (http://support.microsoft.com/default.aspx?scid=kb;en-us;Q305153).

  9. Bhaskar Tripathi says:

    I have found a solution for all the above queries…
    please google for “Itextsharp”. You will find a gr8 API provided by them to CONVERT HTML-2-PDF,ASPX-2-PDF,XLS-2-2PDF.

    Regards
    Bhaskar Tripathi

  10. Steve says:

    How come the Page Load event code for PDFContainer.aspx it works, but does not work when I put in the same code in the code behind file PDFContainer.aspx.cs?

    It works as it is in this demonstration but when I cut that Page Load code and put it in the code behind file I get a blank page.

  11. Sachin says:

    Great post. Needed to save an xls file to the client computer and this post helped me do it in no time.

    Great work!

  12. Neil Gorin says:

    Hi Rahul,

    It is so nice to see your beautiful Anika growing and developing well.  

    I wonder if you think this concept can be extended to downloading images to an image control.  I have several thumbnail images that are not contained in the web root or a subfolder of the web root.  I do not want my users knowledge of the physical path of my images.  

    Regards,

    Neil Gorin

  13. rahulso says:

    Hi Dr. Neil,

    Nice to see your entry here! :o)

    Regarding the same concept being extended for the image control, I would say, it is possible to ensure that "I do not want my users knowledge of the physical path of my images". But if you follow the above methods, u will not be able to get the desired affect.

    I would rather suggest streaming down the image files from the database using response.binarywrite. Although, personally I would rather refrain myself from doing it because of the performance hit.

    If the main task is to ensure that no-one is able to go the folder where you have kept all your graphics, creating a web.config and denying access in some way might be a better solution!!

    You can also probably opt for URL Rewriting. Involves a little bit of coding, but probably the best!

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp

    Thanks,

    Rahul

  14. Mahesh says:

    I need to count the total number of pages in a pDF document using VB.NET.  Is it possible

  15. steve says:

    Hi, could you point out how to use adobe open parameters? trips when using something like: Response.TransmitFile(….SYS.PDF#page=71)

    SYSA.PDF#page=71′ is not a valid virtual path.

    Response.Redirect is working for me either.

    Like to display different page numbers directly from code. Using acrobat 8

    Thanks -Steve

  16. Hi Steve,

    Honestly speaking, I don’t have the answer. I am not aware of the PDF DOM.

    Rahul

  17. ritu says:

    u hav given all the 4 ways for opening pdf file at button click.how could i do it at page load event.when i hav tried to do dats nothing appears on screen whereas at button click every thing goes right

  18. Amit says:

    Hi!

    Great help! :)

  19. Hi Ritu,

    If you notice, to make everything happen as we expect we work with headers.

    The problem with Page Load event is that if you have reached till Page_Load, your headers etc are already sent and you will not get the desirable effect.

    Hope that helps!

    Rahul

  20. nitin says:

    hi,

    how can i convert a .aspx file to pdf file on click of a button and save it to disk.

  21. Saurabh says:

    Good job!

  22. Jim H says:

    I used method 2 but the pop-up blocker(s)

    intercept. In IE, if the user clicks ‘Download’

    the dialog box nerver appears and they have no idea where or if te file was saved.

    How do you get around pop-up blockers and let the user decide whether ot not to download.

    JH

  23. Hi Jim,

    AFAIK, The pop-up blocker is a client side setting and the server will unfortunately have no clue if the client is disabling that download.

    HTH,

    Rahul

  24. hyma says:

    I have a .aspx page and in that page’s code behind, i will get data from database and write client script that would create basic HTML content based on the data from the database.  Now I want this page to be displayed in pdf.  Could you please help, Rahul.

    THe thing with your "four ways to send a pdf file is", you have to have pre-sepecified .pdf file.  Mine is not like that.  It has to create the pdf file on the fly.  Could you please help.

    Thanks in Advance

    Hyma

  25. Henry says:

    TO MAKE IT WORK IN THE PAGE_LOAD IN THE CODE BEHIND !!!

    I had an issue where I couldn’t load the PDF in the page load.  I created the PDF in a memory stream and found that I had to add this to my code –

    Response.ClearHeaders();

    After adding that, the page loads with the PDF.

  26. Gopi says:

    I want to show the PDF file in part of the IE window (like top half of the window) and show other information in the remaining part. How do we do this? Thanks.

  27. Pete says:

    Henry,

    THANK YOU! I was having the same problem, and your solution worked!

  28. Haritha says:

    Hi.. I am having problem with Adobe version 6. The pdf file is not opening with Adobe 6 but the same code is working fine for Adobe 5.

    I am using the below code:

    Response.Clear()

    Response.ClearContent()

    Response.ClearHeaders()

    Response.Buffer=true

    Response.ContentType = "application/pdf" Response.BinaryWrite(Node.nodeTypedValue)

    Response.Flush()

    Response.Close()

    Response.End()

    Any help??

    Thanks

  29. Hi Haritha,

    The sample here were tested against Adobe 7.0+. Unfortunately, I don’t even have the Adobe reader 5.0/6.0.

    Anyways, you may try playing around with commenting out some statements and check if that makes a difference.

    HTH,

    Rahul

  30. Haritha says:

    Hi Rahul,

    Thank you very much for your response.

    I have been trying to fix this. But unfortunately my code is in ASP and couldn’t find any solution as of now.

    Seems like there is some problem with IE and Adobe Reader 6.0 versions as I am able to open the pdf file with the same code using FireFox and Adobe Reader 6.0

    Will post here if I find any solution.

  31. Hello Haritha,

    You may try Fiddler Tool to analyze what’s different.

    Although, even my gut feeling is saying that it is more likely an issue with IE+Adobe 6.0 combo which is causing it.

    Regards,

    Rahul

  32. Haritha says:

    Hello Rahul,

    I am facing a new problem now. With the code provided everything is working fine for the first time but later when I am trying to create the pdf by submitting the form several times, I am getting error "There was an error opening this document. The file cannot be found".

    I am using Adobe version 7.0 and IE 6.0

    Please let me know your thoughts.

    Thanks

  33. Hello Haritha,

    I am not sure why this would be caused because I have tested all these snippets on my box.

    But, a Filemon trace could give you an idea of what’s happening. Run it while there are issues happening on your server and see if you are able to analyze the data to fix the issue.

    Regards,

    Rahul

  34. europhile says:

    Great thread for important issue Rahul.

    Am having problems with opening downloaded Word doc in same window, it works fine for PDFs, JPGs etc but not Word/Excel (2008).

    Have stripped VB code down to your Way1.aspx and also tried the inline:

    Response.AppendHeader("Content-Disposition", "inline;Filename=file.doc/xls")

    However, Word/Excel seems to ignore it and gives the Open/Save dialogue so that Open will do so in a new application, not within the browser. There’s no special overriding MIME mappings on the site itself and nothing specifically set up within IE7 – same thing happens with FireFox anyway, so it seems as though Office has highjacked the ownership and opening of its documents, even though it’s specified explicitly inline within the TransmitFile.

    Has anyone else had this problem? Might be missing something obvious, but this appears to be a major flaw with Office!

  35. Hello Europhile,

    You need to change the ContentType to "application/vnd.ms-excel"…

    Try way2.aspx and modify the Button1_click event.

       protected void Button1_Click(object sender, EventArgs e)

       {

           Response.ClearHeaders();

           Response.ContentType = "application/vnd.ms-excel";

           Response.Clear();

           Response.AppendHeader("Content-Disposition", "attachment;Filename=UML.xlsx");

           Response.TransmitFile("UML.xlsx");

           Response.End();

       }

    Hope this helps,

    Rahul

  36. Europhile says:

    Many thanks Rahul, handy new mime type!

    Unfortunately, this still opens in a new app window after the Open or Save dialogue. Have you tried it with an office doc?

    I changed your AppendHeader from attachment to inline but both do the same thing! Maybe this is where the bug is, it should be fairly generic code but office ignores the inline?

  37. Hello Europhile,

    I guess you are right. I tried the following code and got a security prompt.

       protected void Button1_Click(object sender, EventArgs e)

       {

           Response.ClearHeaders();

           Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

           Response.Clear();

           Response.AppendHeader("Content-Disposition", "inline;Filename=UML.xlsx");

           Response.TransmitFile("UML.xlsx");

           Response.End();

       }

    The following link explains this…

    http://blogs.msdn.com/vsofficedeveloper/pages/Excel-2007-Extension-Warning.aspx

  38. Raja sekhar says:

    Hi,

     I’m trying to download html page with TransmitFile. It is opening in same browser. But I want open in new window. Can you help me on this….

    Rajasekhar

  39. Does not work?? Always giving that the file is damaged or corrupted!

    Response.ClearHeaders();

                   Response.ContentType = "application/zip";

                   Response.Clear();

                   Response.AppendHeader("Content-Disposition", "attachment;Filename=UML.zip");

                   Response.TransmitFile("~/Files/"+"MyZipFolder.zip");

                   Response.End();