Displaying pdf files in a web page from a sql database directly without needing to save them to the server file system

12,423

Solution 1

I created a MVC class called PdfResult that returns a byte array as a PDF file.

The purpose is as follows (can't upload the source code, sorry):

  1. PdfResult inherits from FileStreamResult
  2. Set the Content-Type header to application/pdf
  3. Set the Content-Disposition to either attachment or inline, and set an appropriate file name
  4. Convert your data to a Stream -- if your data is a byte array, then write it to a MemoryStream.

See https://stackoverflow.com/a/16673120/272072 for a good example of how to do this.

Then, your embed code just needs to point to the action method, as if it was a PDF file.
Here's an example:

public ActionResult ShowPdf() {
    // Note: the view should contain a tag like <embed src='MyController/GetPdf'>
    return View(); 
}

public ActionResult GetPdf() {
    byte[] pdfBytes = dataRepo.GetPdf(...);
    return new PdfResult(pdfBytes, "Filename.pdf", false) ;
} 

Solution 2

Here is a link to a CodeProject article and code sample titled Download and Upload Images from SQL Server via ASP.NET MVC. This gives an example of an efficient method to stream content to and from SQL Server via MVC.

You can easily adapt the code to stream your PDF file downloads.

UPDATE

The article uses a DataReader, but it can easily be adapted to Linq2Sql or EF. As an example, here is the Read method where I am reading from the database and copying to the stream:

public override int Read(byte[] buffer, int offset, int count)
{
    result = _attachments.ExecuteStoreQuery<byte[]>(
             "SELECT SUBSTRING(AttachmentBytes, " + position.ToString() +
             ", " + count.ToString() + ") FROM Attachments WHERE Id = {0}",
             id).First();

    var bytesRead = result.Length;
    Buffer.BlockCopy(result, 0, buffer, 0, bytesRead);

    position += bytesRead;
    return (int)bytesRead;
}

Solution 3

You can read the PDF as a bytestream from the database and save it to the http response stream. If you have set the content type correctly to application/pdf, then the browser will load the document in the PDF plugin.

Update (14/Oct/2011): You need to write the bytestream to the Response.OutputStream object. How you create and write the byte stream is dependent on how you have stored in the database and how you are retrieving it. The following code snippet is from an article we have on our website - Generate PDF Forms In ASP.NET Using PDFOne .NET v3.

  // Get the page's output stream ready
  Response.Clear();
  Response.BufferOutput = true;
  // Make the browser display the forms document
  // using a PDF plug-in. (If no plug in is available, 
  // the browser will show the File -> Save As dialog box.
  Response.ContentType = "application/pdf"; 

  // Write the forms document to the browser
  doc.Save(Response.OutputStream);

  doc.Close();
  doc.Dispose();

The doc object is from our component. You need not use that. This code snippet is only for your understanding. For your requirement, you may have to something like bytestream.save(Response.OutputStream) I guess. BTW, this code is for ordinary ASP.NET, not MVC.

DISCLAIMER: I work for Gnostice.

Share:
12,423
Aaron Patten
Author by

Aaron Patten

Updated on August 21, 2022

Comments

  • Aaron Patten
    Aaron Patten over 1 year

    I'm currently using an html embed tag to display a pdf file that is saved on the local server. Is there a wayo to display a pdf file on my page without having to save it to the local file system of the server? I just wand to pass it to the view from the controller in such a way that it can be displayed as a pdf in the page without having it stored on the file system directly.

    Alternatively, is there a way to call a method to delete the pdf file from the server once the user has navigated away from the page they are viewing? How do I tell if th euser has navicated away from the page and how do i cause that to trigger a method that will delete the file?