Rick Kierner
Rick Kierner

Reputation: 714

Stream a PDF to a web page failing

I have a URL to a PDF and I want to serve up the PDF to my page viewer.

I can successfully (I think) retrieve the PDF file. Then when I do the Response.BinaryWrite() I get a "The file is damaged and could not be repaired" error from the adobe reader.

Here's the code I have:

protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            byte[] output = DoWork("Http://localhost/test.pdf");
            Response.Clear();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-disposition", "inline; filename=MyPDF.PDF");
            Response.AddHeader("content-length", output.Length.ToString());
            Response.BinaryWrite(output);
            Response.End();
        }
    }

    public byte[] DoWork(string requestUrl)
    {
        byte[] responseData;
        HttpWebRequest req = null;
        HttpWebResponse resp = null;
        StreamReader strmReader = null;

        try
        {
            req = (HttpWebRequest)WebRequest.Create(requestUrl);

            using (resp = (HttpWebResponse)req.GetResponse())
            {
                byte[] buffer = new byte[resp.ContentLength];
                BinaryReader reader = new BinaryReader(resp.GetResponseStream());
                reader.Read(buffer, 0, buffer.Length);
                responseData = buffer;
            }
        }
        finally
        {
            if (req != null)
            {
                req = null;
            }

            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }

        return responseData;

    }

Upvotes: 2

Views: 5434

Answers (6)

Eduardo Molteni
Eduardo Molteni

Reputation: 39453

You can also try to use FileStream the read the file

 string strPath = Request.PhysicalApplicationPath 
                  + "\\document\\Test.pdf";
 FileStream fStream = new FileStream
            (strPath, FileMode.Open, FileAccess.Read);
 StreamReader sReader = new StreamReader(fStream);

Upvotes: 1

a7drew
a7drew

Reputation: 7811

You might be able to simplify your code quite a bit by using the WebClient class

Here's the MSDN documentation. Its not as cumbersome as the lower level HttpWebRequest class.

Upvotes: 0

Nick
Nick

Reputation: 761

When I did this in Perl the other day (as a quick hack for our intranet), the crux of the script was:

binmode(STDOUT);
print "Content-type: application/pdf\n\n";
binmode(FILE);
print <FILE>;
close(FILE);

The key points being to make sure that the input and output streams are in binary mode, i.e. as you've found, the PDF needs to be interpreted as binary data throughout the chain.

Upvotes: 0

Rick Kierner
Rick Kierner

Reputation: 714

Apparently, I need to use ReadBytes() For some reason, when reading a PDF from a URL, You don't get all of the bytes that you requested.

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            byte[] output = DoWork("Http://localhost/test.pdf");
            Response.Clear();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-disposition", "attachment");
            Response.AddHeader("content-length", output.Length.ToString());
            Response.BinaryWrite(output);
            Response.End();
        }
    }

    public byte[] DoWork(string requestUrl)
    {
        byte[] responseData;
        HttpWebRequest req = null;
        HttpWebResponse resp = null;
        StreamReader strmReader = null;

        try
        {
            req = (HttpWebRequest)WebRequest.Create(requestUrl);

            using (resp = (HttpWebResponse)req.GetResponse())
            {
                byte[] buffer = new byte[resp.ContentLength];
                using (BinaryReader reader = new BinaryReader(resp.GetResponseStream()))
                {
                    buffer = reader.ReadBytes(buffer.Length);
                    reader.Close();
                }
                responseData = buffer;
            }
        }
        finally
        {
            if (req != null)
            {
                req = null;
            }

            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }

        return responseData;

    }

Upvotes: 3

sduplooy
sduplooy

Reputation: 14720

Try to flush the response after the binary write...

Response.BinaryWrite(output);
Response.Flush();
Response.End();

Alternatively, instead of inline, try to output the PDF as an attachment:

Response.AddHeader("Content-Disposition", "attachment;filename=MyPDF.PDF");

Upvotes: 0

Bouke
Bouke

Reputation: 12198

Try saving the resulting file to your disk. Then open the file with a text editor. Maybe there are some errors in your script/source file.

Upvotes: 1

Related Questions