Getting Started with ASP.NET Core PDF Viewer control
The ASP.NET Core PDF Viewer control is used for viewing and printing PDF files in web applications. It provides a rich viewing experience with core interactions such as zooming, scrolling, text search, text selection, and text copying. Built-in thumbnail, bookmark, hyperlink, and table of contents support enables easy navigation within and across PDF files.
This section briefly explains how to integrate the ASP.NET Core PDF Viewer control into an ASP.NET Core application using Visual Studio.
Prerequisites
System requirements for ASP.NET Core controls
For production apps, ensure that a valid Syncfusion license key is registered in the application as described in the ASP.NET Core licensing documentation.
Integrate PDF Viewer into an ASP.NET Core application
- Start Visual Studio and select Create a new project.
- In the Create a new project dialog, select ASP.NET Core Web App.
- In the Configure your new project dialog, enter the project name and select Next.
- In the Additional information dialog, select .NET 6.0 (Long-term Support) or a later LTS version (such as .NET 8), and then select Create.
ASP.NET Core PDF Viewer NuGet package installation
To add the ASP.NET Core PDF Viewer control, the following NuGet package needs to be installed in the ASP.NET Core application:
Add Syncfusion® ASP.NET Core Tag Helper
Open ~/Pages/_ViewImports.cshtml and import the Syncfusion.EJ2 Tag Helper.
@addTagHelper *, Syncfusion.EJ2Add style sheet
Reference the theme using the CDN inside the <head> of ~/Pages/Shared/_Layout.cshtml:
<head>
...
<!-- Syncfusion ASP.NET Core controls styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/31.2.2/fluent.css" />
</head>NOTE
See the Themes topic for different ways to reference styles in an ASP.NET Core application, including CDN, NPM package, and CRG.
Add script reference
Add the required scripts using the CDN inside the <head> of ~/Pages/Shared/_Layout.cshtml:
<head>
...
<!-- Syncfusion ASP.NET Core controls scripts -->
<script src="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2.min.js"></script>
</head>Register Syncfusion® Script Manager
Open ~/Pages/Shared/_Layout.cshtml and register the script manager in the ASP.NET Core application:
<body>
....
....
<!-- Syncfusion ASP.NET Core Script Manager -->
<ejs-scripts></ejs-scripts>
</body>NOTE
Add the script manager
<ejs-script>at the end of the<body>.
Add ASP.NET Core PDF Viewer control
Add the Syncfusion® ASP.NET Core PDF Viewer tag helper in ~/Pages/Index.cshtml. A PDF file can be loaded in the PDF Viewer by setting the document name to the documentPath property, as shown below.
@page "{handler?}"
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<ejs-pdfviewer id="pdfviewer" style="height:600px" serviceUrl="/Index" documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf">
</ejs-pdfviewer>
</div>Add the below code in the Index.cshtml.cs which is placed inside the Pages folder.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Syncfusion.EJ2.PdfViewer;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Reflection;
using System.Net;
namespace PDFViewerSample.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class IndexModel : PageModel
{
private readonly Microsoft.AspNetCore.Hosting.IHostingEnvironment _hostingEnvironment;
private IMemoryCache _cache;
public IndexModel(Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment, IMemoryCache cache)
{
_hostingEnvironment = hostingEnvironment;
_cache = cache;
}
public IActionResult OnPostLoad([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
MemoryStream stream = new MemoryStream();
var jsonObject = JsonConverterstring(responseData);
object jsonResult = new object();
if (jsonObject != null && jsonObject.ContainsKey("document"))
{
if (bool.Parse(jsonObject["isFileName"]))
{
string documentPath = GetDocumentPath(jsonObject["document"]);
if (!string.IsNullOrEmpty(documentPath))
{
byte[] bytes = System.IO.File.ReadAllBytes(documentPath);
stream = new MemoryStream(bytes);
}
else
{
string fileName = jsonObject["document"].Split(new string[] { "://" }, StringSplitOptions.None)[0];
if (fileName == "http" || fileName == "https")
{
WebClient WebClient = new WebClient();
byte[] pdfDoc = WebClient.DownloadData(jsonObject["document"]);
stream = new MemoryStream(pdfDoc);
}
else
return this.Content(jsonObject["document"] + " is not found");
}
}
else
{
byte[] bytes = Convert.FromBase64String(jsonObject["document"]);
stream = new MemoryStream(bytes);
}
}
jsonResult = pdfviewer.Load(stream, jsonObject);
return Content(JsonConvert.SerializeObject(jsonResult));
}
public Dictionary<string, string> JsonConverterstring(jsonObjects results)
{
Dictionary<string, object> resultObjects = new Dictionary<string, object>();
resultObjects = results.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToDictionary(prop => prop.Name, prop => prop.GetValue(results, null));
var emptyObjects = (from kv in resultObjects
where kv.Value != null
select kv).ToDictionary(kv => kv.Key, kv => kv.Value);
Dictionary<string, string> jsonResult = emptyObjects.ToDictionary(k => k.Key, k => k.Value.ToString());
return jsonResult;
}
//Post action for processing the PDF documents.
public IActionResult OnPostRenderPdfPages([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
object jsonResult = pdfviewer.GetPage(jsonObject);
return Content(JsonConvert.SerializeObject(jsonResult));
}
//Post action for unloading and disposing the PDF document resources
public IActionResult OnPostUnload([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
pdfviewer.ClearCache(jsonObject);
return this.Content("Document cache is cleared");
}
//Post action for rendering the ThumbnailImages
public IActionResult OnPostRenderThumbnailImages([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
object result = pdfviewer.GetThumbnailImages(jsonObject);
return Content(JsonConvert.SerializeObject(result));
}
//Post action for processing the bookmarks from the PDF documents
public IActionResult OnPostBookmarks([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
object jsonResult = pdfviewer.GetBookmarks(jsonObject);
return Content(JsonConvert.SerializeObject(jsonResult));
}
//Post action for rendering the annotation comments
public IActionResult OnPostRenderAnnotationComments([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
object jsonResult = pdfviewer.GetAnnotationComments(jsonObject);
return Content(JsonConvert.SerializeObject(jsonResult));
}
//Post action for exporting the annotations
public IActionResult OnPostExportAnnotations([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
string jsonResult = pdfviewer.ExportAnnotation(jsonObject);
return Content(jsonResult);
}
//Post action for importing the annotations
public IActionResult OnPostImportAnnotations([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
string jsonResult = string.Empty;
object JsonResult;
if (jsonObject != null && jsonObject.ContainsKey("fileName"))
{
string documentPath = GetDocumentPath(jsonObject["fileName"]);
if (!string.IsNullOrEmpty(documentPath))
{
jsonResult = System.IO.File.ReadAllText(documentPath);
}
else
{
return this.Content(jsonObject["document"] + " is not found");
}
}
else
{
string extension = Path.GetExtension(jsonObject["importedData"]);
if (extension != ".xfdf")
{
JsonResult = pdfviewer.ImportAnnotation(jsonObject);
return Content(JsonConvert.SerializeObject(JsonResult));
}
else
{
string documentPath = GetDocumentPath(jsonObject["importedData"]);
if (!string.IsNullOrEmpty(documentPath))
{
byte[] bytes = System.IO.File.ReadAllBytes(documentPath);
jsonObject["importedData"] = Convert.ToBase64String(bytes);
JsonResult = pdfviewer.ImportAnnotation(jsonObject);
return Content(JsonConvert.SerializeObject(JsonResult));
}
else
{
return this.Content(jsonObject["document"] + " is not found");
}
}
}
return Content(jsonResult);
}
//Post action for downloading the PDF documents
public IActionResult OnPostDownload([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
string documentBase = pdfviewer.GetDocumentAsBase64(jsonObject);
return Content(documentBase);
}
//Post action for printing the PDF documents
public IActionResult OnPostPrintImages([FromBody] jsonObjects responseData)
{
PdfRenderer pdfviewer = new PdfRenderer(_cache);
var jsonObject = JsonConverterstring(responseData);
object pageImage = pdfviewer.GetPrintImage(jsonObject);
return Content(JsonConvert.SerializeObject(pageImage));
}
//Gets the path of the PDF document
private string GetDocumentPath(string document)
{
string documentPath = string.Empty;
if (!System.IO.File.Exists(document))
{
string basePath = _hostingEnvironment.WebRootPath;
string dataPath = string.Empty;
dataPath = basePath + "/";
if (System.IO.File.Exists(dataPath + (document)))
documentPath = dataPath + document;
}
else
{
documentPath = document;
}
return documentPath;
}
}
public class jsonObjects
{
public string document { get; set; }
public string password { get; set; }
public string zoomFactor { get; set; }
public string isFileName { get; set; }
public string xCoordinate { get; set; }
public string yCoordinate { get; set; }
public string pageNumber { get; set; }
public string documentId { get; set; }
public string hashId { get; set; }
public string sizeX { get; set; }
public string sizeY { get; set; }
public string startPage { get; set; }
public string endPage { get; set; }
public string stampAnnotations { get; set; }
public string textMarkupAnnotations { get; set; }
public string stickyNotesAnnotation { get; set; }
public string shapeAnnotations { get; set; }
public string measureShapeAnnotations { get; set; }
public string action { get; set; }
public string pageStartIndex { get; set; }
public string pageEndIndex { get; set; }
public string fileName { get; set; }
public string elementId { get; set; }
public string pdfAnnotation { get; set; }
public string importPageList { get; set; }
public string uniqueId { get; set; }
public string data { get; set; }
public string viewPortWidth { get; set; }
public string viewPortHeight { get; set; }
public string tilecount { get; set; }
public bool isCompletePageSizeNotReceived { get; set; }
public string freeTextAnnotation { get; set; }
public string signatureData { get; set; }
public string fieldsData { get; set; }
public string formDesigner { get; set; }
public string inkSignatureData { get; set; }
public bool hideEmptyDigitalSignatureFields { get; set; }
public bool showDigitalSignatureAppearance { get; set; }
public bool digitalSignaturePresent { get; set; }
public string tileXCount { get; set; }
public string tileYCount { get; set; }
public string digitalSignaturePageList { get; set; }
public string annotationCollection { get; set; }
public string annotationsPageList { get; set; }
public string formFieldsPageList { get; set; }
public bool isAnnotationsExist { get; set; }
public bool isFormFieldAnnotationsExist { get; set; }
public string documentLiveCount { get; set; }
public string annotationDataFormat { get; set; }
public string importedData { get; set; }
}
}In the preceding code:
- The ejs-pdfviewer tag helper renders the PDF Viewer control with the id
pdfviewer. - The serviceUrl property specifies the endpoint used by the viewer to communicate with the server. In this Razor Pages sample, it targets the
Indexpage handlers (OnPost...methods) inIndexModel. - The documentPath property specifies the PDF file to load in the viewer.
Press Ctrl+F5 (Windows) or ⌘+F5 (macOS) to run the app. The Syncfusion® ASP.NET Core PDF Viewer control renders in the default web browser.

NOTE
The
serviceUrlcan be changed dynamically. After updating the value at runtime, invokepdfViewer.dataBind()to apply the change, and then load the document. Ensure that this approach is used with version 23.1.36 or later.
function load() {
var pdfViewer = document.getElementById(‘pdfviewer’).ej2_instances[0];
pdfViewer.serviceUrl = “/Index”;
pdfViewer.documentPath = “https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf”;
pdfViewer.dataBind();
pdfViewer.load(pdfViewer.documentPath, null);
}
NOTE
NOTE
When configuring the server-backed PDF Viewer, there is no need to include the
pdfium.jsandpdfium.wasmfiles. Unlike the standalone PDF Viewer, which performs client-side rendering, the server-backed PDF Viewer processes and renders PDFs on the server. As a result, omit any copy commands for these files during deployment.
NOTE
For hosting the web service on Linux, include SkiaSharp.NativeAssets.Linux. For AWS environments, use the following packages:
| Amazon Web Services (AWS) | NuGet package name |
|---|---|
| AWS Lambda | SkiaSharp.NativeAssets.Linux |
| AWS Elastic Beanstalk | SkiaSharp.NativeAssets.Linux.NoDependencies v3.116.1 |