-2

I have a web api controller that is returning PDF. Some PDFs are not being opened by Abobe Reader XI 11.0.12

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.BinaryWrite(myByteArray);
HttpContext.Current.Response.End();

The above code works without errors, and PDFs can be opened in Adobe Reader as well in all popular browsers.

But it does throw "Server cannot set status after HTTP headers have been sent." which I have been ignoring but would like to resolve, so I implement the below code.

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.BufferOutput = true;
HttpContext.Current.Response.BinaryWrite(myByteArray);
HttpContext.Current.Response.Flush();

This code also works without errors, but the PDF returned from this code cannot be opened in Adobe Reader XI version 11.0.12. FF, Chrome, Edge can show the PDF fine. IE 11 cannot.

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

enter image description here

joym8
  • 4,014
  • 3
  • 50
  • 93
  • 1
    If one browser can read that PDF and other can't, you're looking for a problem in a wrong place. It's most probably problem with PDF content, not with the way you send it to browser. – Dominik Szymański Apr 26 '19 at 16:42
  • 1
    Can you please provide code about where binaryObject comes from ? I do not see this variable being initialize any where – Dalorzo Apr 26 '19 at 17:15
  • @Dalorzo i have updated the question – joym8 Apr 26 '19 at 17:48
  • 1
    You need to end the response after you write the file bytes. Otherwise other content will end up getting written to the file, thus corrupting the PDF. Why are you writing directly to the response in Web API anyways. Don't do that! Web API has [action results for returning files](https://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api). – mason Apr 26 '19 at 17:51
  • 1
    You probably got "Server cannot set status after HTTP headers have been sent." because you wrote headers to the response, then ended the response, thus causing an exception, thus causing Web API to try to set the HTTP status code to 500, thus causing an additional error. All of which could be avoided by properly returning a file from your action method. – mason Apr 26 '19 at 17:54
  • Posting for reference https://helpx.adobe.com/acrobat/kb/pdf-error-1015-11001-update.html – joym8 Apr 26 '19 at 19:05
  • @mason what step are you referring to when you say don't write response directly to web api? – joym8 Apr 26 '19 at 19:54
  • 1
    In Web API you should not write to the response. That's not your job. That's the framework's job. So all those `HttpContext.Current.Response` calls in your code need to go away. Instead, return an action result that contains the contents of the file. You can easily do a web search for how to return a file in Web API. – mason Apr 26 '19 at 19:56
  • @mason you want to add that as an answer? it has resolved my issue. – joym8 Apr 26 '19 at 19:57
  • No, you can put your own code that you used to resolve it as an answer. – mason Apr 26 '19 at 19:58

1 Answers1

1

Based on @mason response and the link Returning binary file from controller in ASP.NET Web API I replaced all HttpContext.Current.Response with the following code to resolve this issue:

public HttpResponseMessage LoadPdf(int id)
{
    //get PDF in myByteArray

    //return PDF bytes as HttpResponseMessage
    HttpResponseMessage result = new HttpResponseMessage();
    Stream stream = new MemoryStream(myByteArray);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "my-doc.pdf" };
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    result.StatusCode = HttpStatusCode.OK;
    return result;
}
joym8
  • 4,014
  • 3
  • 50
  • 93