Heath Allison
Heath Allison

Reputation:

Reporting Services as PDF through WebRequest in C# 3.5 "Not Supported File Type"

I've inherited a legacy application that is supposed to grab an on the fly pdf from a reporting services server. Everything works fine up until the point where you try to open the pdf being returned and adobe acrobat tells you:

Adobe Reader could not open 'thisStoopidReport'.pdf' because it is either not a supported file type or because the file has been damaged(for example, it was sent as an email attachment and wasn't correctly decoded).

I've done some initial troubleshooting on this. If I replace the url in the WebRequest.Create() call with a valid pdf file on my local machine ie: @"C:temp/validpdf.pdf") then I get a valid PDF.

The report itself seems to work fine. If I manually type the URL to the reporting services report that should generate the pdf file I am prompted for user authentication. But after supplying it I get a valid pdf file.

I've replace the actual url,username,userpass and domain strings in the code below with bogus values for obvious reasons.

        WebRequest request = WebRequest.Create(@"http://x.x.x.x/reportServer?/reports/reportNam&rs:format=pdf&rs:command=render&rc:parameters=blahblahblah");
        int totalSize = 0;
        request.Credentials = new NetworkCredential("validUser", "validPass", "validDomain");
        request.Timeout = 360000; // 6 minutes in milliseconds.
        request.Method = WebRequestMethods.Http.Post;
        request.ContentLength = 0;
        WebResponse response = request.GetResponse();
        Response.Clear();
        BinaryReader reader = new BinaryReader(response.GetResponseStream());
        Byte[] buffer = new byte[2048];
        int count = reader.Read(buffer, 0, 2048);
        while (count > 0)
        {
            totalSize += count;
            Response.OutputStream.Write(buffer, 0, count);
            count = reader.Read(buffer, 0, 2048);
        }
        Response.ContentType = "application/pdf";
        Response.Cache.SetCacheability(HttpCacheability.Private);
        Response.CacheControl = "private";
        Response.Expires = 30;
        Response.AddHeader("Content-Disposition", "attachment; filename=thisStoopidReport.pdf");
        Response.AddHeader("Content-Length", totalSize.ToString());
        reader.Close();
        Response.Flush();
        Response.End();

Upvotes: 4

Views: 8461

Answers (3)

Heath Allison
Heath Allison

Reputation:

Those of you who suggested the problem was HTML coming back from the URL pointed me in the right direction. In fact that's when I realized the original programmer on here used the PUT instead of GET method.

So by correcting the single line:

request.Method = WebRequestMethods.Http.Post;

Everything is now coming up roses... err pdf... whatever it works.

Thanks for pointing me in the right direction. Sometimes it just takes a second set of eyes.

Upvotes: 1

Ron Todosichuk
Ron Todosichuk

Reputation: 284

View the pdf file that you get back in notepad.exe. I suspect that you will see HTML in there. If you call a web page that is a pass through page, that severs up a pdf file. The web request will get back the HTML not the PDF file.

If you call a web site that has a pdf file directly, like http://www.somesite.com/file.pdf your code will work. The problem is that you probably have a pass through web page that hides the true location of the pdf file.

The way I have gotten around this was to create an ISAPI DLL that allowed you to pass in the parameters it need to determine what pdf file need to be sent back. Than the ISAPI DLL would stream back the pdf with a content type of "application/pdf".

Upvotes: 1

Jeremy
Jeremy

Reputation: 219

Could your problem be caused by declaring your byte array to a length of 2048 rather than basing the length on the length of the stream returned by GetResponseStream()?

Upvotes: 0

Related Questions