Telerik blogs
DotNetT2 Dark_1200x303

Having troubles loading your PDF files in the Telerik PdfViewer for ASP.NET AJAX? Take a few minutes to check out these options—I bet you won’t regret it!

The purpose of this blog post is to reveal some known and unknown techniques of loading PDF files/content in RadPdfViewer for ASP.NET AJAX, explaining them with examples in order to help you incorporate the UI component in a more diverse set of applications and scenarios. Either on the server or on the client, via virtual or physical paths, from a file or a database, via local or remote file destinations, via URL, via memory streams and even via a Base64 string—this is all possible thanks to the advanced API of the component.

Let’s dive deeper and check out the possibilities to load a PDF file one by one:

Accessible File on Another Domain

Loading a file via URL on another domain is simple and straightforward with RadPdfViewer. The File property of the component is exposed particularly to pass a path pointing to an existing PDF file.

The File property can be set in the PdfjsProcessingSettings inner tag of RadPdfViewer.

<telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
</PdfjsProcessingSettings>
</telerik:RadPdfViewer>

A common problem with presenting a file from an external domain is the cross-domain accessibility. So as long as the CORS policy of the server where the PDF file is located allows remote access, the RadPdfViewer should be able to display that document. Check out the following resources discussing this topic:

When the file is not accessible due to CORS policy, a JavaScript error indicating the problem is thrown on the browser’s console:

Error window says 'PDF fails to process.' and the Console shows 'Access to fetch [URL] from origin [localhost] has been blocked by CORS policy...'

File in the Application Folder—Using Local or Relative Path

The approach for loading a locally positioned PDF file in the RadPdfViewer is the same as the one above. You should only set a relative path to the file property and, in this case, you should not worry about the cross-origin issue.

There are three ways to set the file path:

  • Define the path in the declaration of the control:
    <telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
    <PdfjsProcessingSettings File="Content/Document.pdf">
    </PdfjsProcessingSettings>
    </telerik:RadPdfViewer>
  • Set the file path in the code-behind:
    <telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9" OnLoad="RadPdfViewer1_Load">
    </telerik:RadPdfViewer>
    C#
    protected void RadPdfViewer1_Load(object sender, EventArgs e)
    {
    (sender as RadPdfViewer).PdfjsProcessingSettings.File = "Content/Document.pdf";
    }
    VB
    Protected Sub RadPdfViewer1_Load(ByVal sender As Object, ByVal e As EventArgs)
    (TryCast(sender, RadPdfViewer)).PdfjsProcessingSettings.File = "Content/Document.pdf"
    End Sub
  • Set the path on the client side:
    <script>
    function pdfViewerLoad(sender, args) {
    var pdfViewer = sender;
    pdfViewer.fromFile("http://localhost:29842/Document.pdf");
    }
    </script>
    <telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
    <ClientEvents OnLoad="pdfViewerLoad" />
    </telerik:RadPdfViewer>

Important note: The rendering engine of the RadPdfViewer operates completely on the client side; therefore, in all the cases where an absolute or relative path is passed to the control, an additional HTTP request is performed to fetch the file.

Information about the request for fetching the file from the server can be seen in the Network tab of the Browser’s DevTools as shown below:

In the Network tab, hovering on the Document.pdf brings up a tooltip with the localhost URL.

File Stored on the Host Machine, Out of the App Folder

How to load a file from a local machine?

You can access any files located in a virtual folder that is a subfolder of the web application. This means that you can create a virtual directory that is a subdirectory of the web application folder pointing to a physical folder located on the machine. You also have to set the needed ASPNET/NETWORK SERVICE permissions to this virtual directory.

For more information, check out How to: Create a virtual directory with IIS Manager for an ASP.NET application.

File from FileStream (MemoryStream)

A common scenario is when the PDF file that is about to be loaded it in the PDF viewer is not yet an existing file. In cases when the PDF is generated programmatically, there are two main options to populate the file to the user:

Option 1: Save the file on the server and provide its path to the RadPdfViewer.

Option 2: Convert the file stream to a Base64 string and assign it as data of the RadPdfViewer.

Sample implementation of this approach is demonstrated in our live demo: Convert, View and Download Different Formats.

Note: Have in mind that the Base64 string may become too long depending on the content of the file and that could cause performance issues when transferring to the client side.

Below is sample code showing both options. To test Option 1, uncomment the relevant code and comment the piece related to Option 2. For generating the PDF file in the sample, we have used the Telerik Document Processing Libraries, so make sure all the required assemblies are referenced before testing the approach:

ASPX
<telerik:RadScriptManager ID="RadScriptManager1" runat="server"></telerik:RadScriptManager>
<script type="text/javascript">
window.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.worker.js';
function pageLoad(app, args) {
var upload = $find('<%= RadAsyncUpload1.ClientID %>');
$telerik.$(upload.get_element()).find("input[type='file']").attr("accept", ".docx, .rtf, .html, .txt, .xlsx, .csv");
}
</script>
<telerik:RadAsyncUpload ID="RadAsyncUpload1" runat="server"
OnFileUploaded="RadAsyncUpload1_FileUploaded"
AllowedFileExtensions=".docx,.rtf,.html,.txt,.xlsx,.csv" HideFileInput="true"
AutoAddFileInputs="false" Localization-Select="Upload And Convert" EnableInlineProgress="false"
MultipleFileSelection="Disabled" />
<telerik:RadButton runat="server" ID="RadButton1" Text="Submit File" AutoPostBack="true" />
<telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
<PdfjsProcessingSettings File="Content/Document.pdf"></PdfjsProcessingSettings>
</telerik:RadPdfViewer>
C#
protected void Page_Load(object sender, EventArgs e)
{
int maxSize = 10 * 1024 * 1024; // 10MB
RadAsyncUpload1.MaxFileSize = maxSize;
RadPdfViewer1.MaxSerializerLength = maxSize;
}
protected void RadAsyncUpload1_FileUploaded(object sender, FileUploadedEventArgs e)
{
byte[] renderedBytes = null;
string extention = Path.GetExtension(e.File.FileName);
// RadFlow Documents
if (Regex.IsMatch(extention, ".docx|.rtf|.html|.txt"))
{
IFormatProvider<RadFlowDocument> provider = null;
RadFlowDocument document = null;
switch (extention)
{
case ".docx": provider = new DocxFormatProvider(); break;
case ".rtf": provider = new RtfFormatProvider(); break;
case ".html": provider = new HtmlFormatProvider(); break;
case ".txt": provider = new TxtFormatProvider(); break;
default: provider = null; break;
}
document = provider.Import(e.File.InputStream);
Telerik.Windows.Documents.Flow.FormatProviders.Pdf.PdfFormatProvider pdfProvider = new
Telerik.Windows.Documents.Flow.FormatProviders.Pdf.PdfFormatProvider();
using (MemoryStream ms = new MemoryStream())
{
pdfProvider.Export(document, ms);
renderedBytes = ms.ToArray();
}
}
// Workbook Documents
else if (Regex.IsMatch(extention, ".xlsx|.csv"))
{
IWorkbookFormatProvider provider = null;
Workbook document = null;
switch (extention)
{
case ".xlsx": provider = new XlsxFormatProvider(); break;
case ".csv": provider = new CsvFormatProvider(); break;
default: provider = null; break;
}
document = provider.Import(e.File.InputStream);
Telerik.Windows.Documents.Spreadsheet.FormatProviders.Pdf.PdfFormatProvider pdfProvider = new
Telerik.Windows.Documents.Spreadsheet.FormatProviders.Pdf.PdfFormatProvider();
using (MemoryStream ms = new MemoryStream())
{
pdfProvider.Export(document, ms);
renderedBytes = ms.ToArray();
}
}
////option 1 - save file locally and set its path to the pdf viewer
//string relativePath = @"\Content\" + e.File.GetNameWithoutExtension() + ".pdf";
//string path = AppDomain.CurrentDomain.BaseDirectory + relativePath;
//File.WriteAllBytes(path, renderedBytes);
//RadPdfViewer1.PdfjsProcessingSettings.File = relativePath;
//option2 - convert the file to base64 string and set it as pdfviewer's data
RadPdfViewer1.PdfjsProcessingSettings.FileSettings.Data = Convert.ToBase64String(renderedBytes);
}
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim maxSize As Integer = 10 * 1024 * 1024 '10MB
RadAsyncUpload1.MaxFileSize = maxSize
RadPdfViewer1.MaxSerializerLength = maxSize
End Sub
Protected Sub RadAsyncUpload1_FileUploaded(sender As Object, e As Telerik.Web.UI.FileUploadedEventArgs)
Dim renderedBytes As Byte() = Nothing
Dim extention As String = System.IO.Path.GetExtension(e.File.FileName)
'RadFlow Documents
If Regex.IsMatch(extention, ".docx|.rtf|.html|.txt") Then
Dim provider As IFormatProvider(Of RadFlowDocument) = Nothing
Dim document As RadFlowDocument = Nothing
Select Case extention
Case ".docx"
provider = New DocxFormatProvider()
Case ".rtf"
provider = New RtfFormatProvider()
Case ".html"
provider = New HtmlFormatProvider()
Case ".txt"
provider = New TxtFormatProvider()
Case Else
provider = Nothing
End Select
document = provider.Import(e.File.InputStream)
Dim pdfProvider As Telerik.Windows.Documents.Flow.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Flow.FormatProviders.Pdf.PdfFormatProvider()
Using ms As MemoryStream = New MemoryStream()
pdfProvider.Export(document, ms)
renderedBytes = ms.ToArray()
End Using
'Workbook Documents
ElseIf Regex.IsMatch(extention, ".xlsx|.csv") Then
Dim provider As IWorkbookFormatProvider = Nothing
Dim document As Workbook = Nothing
Select Case extention
Case ".xlsx"
provider = New XlsxFormatProvider()
Case ".csv"
provider = New CsvFormatProvider()
Case Else
provider = Nothing
End Select
document = provider.Import(e.File.InputStream)
Dim pdfProvider As Telerik.Windows.Documents.Spreadsheet.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Spreadsheet.FormatProviders.Pdf.PdfFormatProvider()
Using ms As MemoryStream = New MemoryStream()
pdfProvider.Export(document, ms)
renderedBytes = ms.ToArray()
End Using
End If
''option 1 - save file locally and set its path to the pdf viewer
'Dim relativepath As String = "\content\" + e.File.GetNameWithoutExtension() + ".pdf"
'Dim path As String = AppDomain.CurrentDomain.BaseDirectory + relativepath
'File.WriteAllBytes(path, renderedBytes)
'RadPdfViewer1.PdfjsProcessingSettings.File = relativepath
'option2 -Convert the file to Base64 string And set it as pdfviewer's data
RadPdfViewer1.PdfjsProcessingSettings.FileSettings.Data = Convert.ToBase64String(renderedBytes)
End Sub

Note: In its essence, the approach in Option 1 shows how to save the programmatically generated file on the server. Once the file has a physical path, you can follow the same steps and notes as in the File in the application folder—using local or relative path section.

The same functionality can be achieved via Ajax Request (instead of PostBack) to improve the user experience. The code-behind, in this case, stays the same.

Here is the markup with the needed Ajax settings (the Submit button will not be needed in this approach):

ASPX
<telerik:RadScriptManager ID="RadScriptManager1" runat="server"></telerik:RadScriptManager>
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script type="text/javascript">
window.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.worker.js';
function pageLoad(app, args) {
var upload = $find('<%= RadAsyncUpload1.ClientID %>');
$telerik.$(upload.get_element()).find("input[type='file']").attr("accept", ".docx, .rtf, .html, .txt, .xlsx, .csv");
}
function fileUploaded(sender, args) {
$find('<%= RadAjaxManager1.ClientID %>').ajaxRequest();
}
</script>
</telerik:RadScriptBlock>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" EnablePageHeadUpdate="false">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadAsyncUpload1" />
<telerik:AjaxUpdatedControl ControlID="RadPdfViewer1" LoadingPanelID="RadAjaxLoadingPanel1" />
<telerik:AjaxUpdatedControl ControlID="RadLabel1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadAsyncUpload ID="RadAsyncUpload1" runat="server"
OnFileUploaded="RadAsyncUpload1_FileUploaded" OnClientFileUploaded="fileUploaded"
AllowedFileExtensions=".docx,.rtf,.html,.txt,.xlsx,.csv" HideFileInput="true"
AutoAddFileInputs="false" Localization-Select="Upload And Convert" EnableInlineProgress="false"
MultipleFileSelection="Disabled" />
<telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
<PdfjsProcessingSettings File="Content/Document.pdf"></PdfjsProcessingSettings>
</telerik:RadPdfViewer>

Hitting the Upload and Convert button pops up an Open window. A .docs document is selected from the file explorer and Open is hit. The document opens in the PDF Viewer.

File Represented by a Base64 String on the Client Side

You can populate a PDF file to the viewer entirely on the client side. With the help of the fromFile() client-side method, exposed by the RadPdfViewer client-side control object, you can set a Base64 string directly on the client.

Here is a sample scenario where a PDF generated by RadClientExportManager is passed to a RadPdfViewer using the client-side APIs of the controls:

ASPX
<telerik:RadScriptManager ID="RadScriptManager1" runat="server"></telerik:RadScriptManager>
<script type="text/javascript">
window.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.worker.js';
</script>
<div id="main">
<input type="text" placeholder="Type your name" value="John" />
<input type="text" placeholder="Type your comment" value="Smith" />
<telerik:RadPushButton OnClientClicked="exportPDF" runat="server" Text="Export page to PDF" ID="Export1" AutoPostBack="false"></telerik:RadPushButton>
</div>
<telerik:RadClientExportManager runat="server" ID="RadClientExportManager1" OnClientPdfExporting="OnClientPdfExporting">
</telerik:RadClientExportManager>
<telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="550px" Width="100%" Scale="0.9">
</telerik:RadPdfViewer>
JavaScript
var $ = $telerik.$;
function exportPDF() {
$find('<%=RadClientExportManager1.ClientID%>').exportPDF($("#main"));
}
function OnClientPdfExporting(sender, args) {
var data = args.get_dataURI().split(',')[1];
setData(data);
args.set_cancel(true);
}
function setData(data) {
var RadPdfViewerObject = $find("<%=RadPdfViewer1.ClientID %>");
RadPdfViewerObject.fromFile({ data: data });
return false;
}

In two separate fields, 'John' and

The whole demo is accessible here, so go and give it a spin.

Wrap-up

Having the know-how shared across this blog post, you can now cover all scenarios related to loading PDF contents, files or streams into the RadPdfViewer component. If you stumble upon a different scenario, something useful or just want to share a tip of your own, do not hesitate to place it in the comments section below.

If you like the PdfViewer, you can further play with it at the online demos as well as download its absolutely free and fully functional trial and give it a spin. We value any feedback and the community voice, which you can share at the Feedback Portal too.

Start a Free Trial


Doncho Milkov
About the Author

Doncho Milkov

Doncho Milkov was a Technical Support Officer working with the Progress Telerik UI for ASP.NET AJAX components.

Related Posts

Comments

Comments are disabled in preview mode.