Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load PDF from memory into telerik:RadPdfViewer

I have a PDF file stored in a database as a byte array. I'm reading the PDF byte array from my database back into my application.

Now, I'm trying to display the PDF with the RadPdfViewer but it is not working.

Here is my code:

    byte[] pdfAsByteArray= File.ReadAllBytes(@"C:\Users\Username\Desktop\Testfile.pdf");

    //Save "pdfAsByteArray" into database
    //...
    //Load pdf from database into byte[] variable "pdfAsByteArray"

    using (var memoryStream = new MemoryStream(pdfAsByteArray))
    {
        this.PdfViewer.DocumentSource = new PdfDocumentSource(memoryStream);
    }

when I execute the application I just get an empty PdfViewer.

Question: How do I set the DocumentSource the right way?

Question: How do I dispose the stream? (note that using doesn't works)

Note: I wan't to avoid things like writing a temp file to disk


Edit:

I figured it out but I am not completely satisfied with this solution:

Not working:

using (var memoryStream = new MemoryStream(pdfAsByteArray))
{
    this.PdfViewer.DocumentSource = new PdfDocumentSource(memoryStream);
}

Working:

var memoryStream = new MemoryStream(pdfAsByteArray);
this.PdfViewer.DocumentSource = new PdfDocumentSource(memoryStream);

I don't know how teleriks RadPdfViewer component works but I wan't to dispose the Stream.

like image 628
Joel Avatar asked Jan 29 '14 14:01

Joel


2 Answers

From the Telerik documentation (particularly with regards to the "Caution" stating that this loading is done asynchronously), I believe this should work while still providing you a way to close the stream (not as cleanly as if you were able to use a using block, but still better than leaving it open):

//class variable
private MemoryStream _stream;

_stream = new MemoryStream(pdfAsByteArray);
var docSource = new PdfDocumentSource(memoryStream);
docSource.Loaded += (sender, args) => { if (_stream != null) _stream.Dispose();};
this.PdfViewer.DocumentSource = docSource;

I did this free-hand and don't have access to the Telerik API so the exact details of the Loaded event are not available to me.

EDIT
Here's the relevant details from documentation I found (emphasis mine):

The PdfDocumentSource loads the document asynchronously. If you want to obtain a reference to the DocumentSource after you have imported a document, you should use the Loaded event of the PdfDocumentSource object to obtain the loaded document. This is also a convenient method that can be used to close the stream if you are loading a PDF from a stream.

like image 84
Sven Grosen Avatar answered Oct 11 '22 15:10

Sven Grosen


You need to implement PdfDocumentSource Loaded event. This is when the stream gets loaded and used up, and can be closed / disposed at that time.

like image 20
Dmitriy Khaykin Avatar answered Oct 11 '22 14:10

Dmitriy Khaykin