2
votes

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;

    }
6
are you able to download it using this, I mean letting a browser (or wget) do the work?falstro

6 Answers

3
votes

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;

    }
1
votes

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.

1
votes

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);
0
votes

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");
0
votes

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.

0
votes

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.