Load PDF from memory into telerik:RadPdfViewer
Asked Answered
T

3

5

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.

Therefrom answered 29/1, 2014 at 14:21 Comment(0)
W
8

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.

Wivinia answered 29/1, 2014 at 15:3 Comment(2)
I wonder if the telerik component will automatically dispose the stream once the loading is finished. I have a support request pending to clarify this issue.Therefrom
@DavidKhaykin I saw your original answer, did a little digging and found that tidbit about the Loaded event, wrote up/submitted my example, and saw that you had suggested the same thing. Great minds think alike.Wivinia
A
2

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.

Arteaga answered 29/1, 2014 at 14:49 Comment(1)
The awkward thing is that it only works without the using blockTherefrom
T
0

Another method I've used is:

this.PdfViewer.PdfjsProcessingSettings.FileSettings.Data = Convert.ToBase64String(File.ReadAllBytes(@"C:\Users\Username\Desktop\Testfile.pdf"));
Teahouse answered 14/6, 2021 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.