12

I am receiving a byte[] which contains a PDF.

I need to take the byte[] and display the PDF in the browser. I have found similar questions like this - How to return PDF to browser in MVC?. But, it opens the PDF in a PDF viewer, also I am getting an error saying the file couldn't be opened because it's - "not a supported file type or because the file has been damaged".

How can I open the PDF in the browser? My code so far looks like the following -

    public ActionResult DisplayPDF()
    {
        byte[] byteArray = GetPdfFromDB();
        Stream stream = new MemoryStream(byteArray);
        stream.Flush(); 
        stream.Position = 0; 

        return File(stream, "application/pdf", "Labels.pdf");
    }
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56
A Bogus
  • 3,852
  • 11
  • 39
  • 58

2 Answers2

13

If you already have the byte[], you should use FileContentResult, which "sends the contents of a binary file to the response". Only use FileStreamResult when you have a stream open.

public ActionResult DisplayPDF()
{
    byte[] byteArray = GetPdfFromDB();

    return new FileContentResult(byteArray, "application/pdf");
}
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56
  • 1
    This worked perfect for me. Using JavaScript to open a small window and call the controller I was able to use the above code to pull out a pdf image from the database. window.open('GetInvoiceImage?ExternalImage=' + ExternalImage, 'Image_win', 'width=800,height=500,left=0,top=0,scrollbars=yes,resizable=yes,menubar=yes'); – Deathstalker Oct 17 '19 at 15:46
12

You can show the byte array PDF directly in your browser simply by using MemoryStream instead of Stream and FileStreamResult instead of File:

public ActionResult DisplayPDF()
{
    byte[] byteArray = GetPdfFromDB();
    using( MemoryStream pdfStream = new MemoryStream())
    {
        pdfStream.Write(byteArray , 0,byteArray .Length);
        pdfStream.Position = 0;
        return new FileStreamResult(pdfStream, "application/pdf");
    }
}
Mohsin
  • 692
  • 1
  • 7
  • 15
Roberto C.
  • 121
  • 1
  • 3
  • 1
    Hey! Put that in a using clause! – Rob Mar 17 '17 at 11:58
  • 4
    @Rob MVC disposes of streams in fileresults for you, because you cant wrap it in a using clause (the stream will be disposed before MVC gets a chance to read it) – berkeleybross Jul 23 '17 at 03:39
  • Use `Response.AddHeader("content-disposition", "inline;filename=Test.pdf");` to set the filename but not download the file immediately. You get `Response` for example by subclassing `System.Web.Mvc.Controller` when you have an MVC app. – bugybunny Oct 12 '18 at 14:30
  • inline + filename doesn’t seem to be a correct header. Chrome and Firefox respect the set username but Edge does not. So be careful and aware of that. – bugybunny Oct 12 '18 at 14:49