[]
This tutorial shows how to use Document Solutions for PDF (DsPdf) and Document Solutions PDF Viewer (DsPdfViewer) in an ASP.NET Core (.NET 8) application. You will generate a PDF on the server with DsPdf, save it to the application’s wwwroot folder, and display it in the browser using the JavaScript-based DsPdfViewer.
By the end of this tutorial, you will have an ASP.NET Core application that creates a branded PDF file, serves it as a static file, and loads it into a browser-based PDF viewer. You will also learn how DsPdfViewer can support advanced client-side editing features when paired with the SupportApi.
Before you begin, make sure you have the following installed:
Visual Studio 2022
.NET 8 SDK
Node.js and npm
A trial or licensed version of Document Solutions for PDF
Once your environment is ready, you can create the ASP.NET Core project and add the required PDF generation and viewer packages.
Open Visual Studio 2022 and create a new ASP.NET Core Web App project.

For this tutorial, use the Razor Pages project template and name the project CreatePdf_DocSol.

When prompted to select a framework, choose .NET 8.0.

After the project is created, Visual Studio will generate the default Razor Pages structure, including the Pages folder, wwwroot folder, and application startup files.
The server-side PDF generation logic uses Document Solutions for PDF. To add DsPdf to your ASP.NET Core application, install the Ds.Documents.Pdf NuGet package.
In Visual Studio, open the NuGet Package Manager using either of the following options:
Right-click the project in Solution Explorer and select Manage NuGet Packages
Go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution
In the NuGet Package Manager, set the package source to NuGet Gallery, open the Browse tab, search for Ds.Documents.Pdf, and install the package.

After installation, the project can use DsPdf classes to create, modify, and save PDF documents from C#.
The PDF will be generated from the Razor Page model in Index.cshtml.cs. Because the generated PDF needs to be loaded by the browser, it should be saved to the application’s wwwroot folder.
To access that folder from server-side code, inject IWebHostEnvironment into the page model constructor. Then call a PDF generation method when the page model is created.
Open Pages/Index.cshtml.cs and add the following fields and constructor logic:
private readonly ILogger<IndexModel> _logger;
private readonly IWebHostEnvironment _environment;
public IndexModel(ILogger<IndexModel> logger, IWebHostEnvironment environment)
{
_logger = logger;
_environment = environment;
CreatePdf();
}Next, add the CreatePdf method. This method creates a one-page PDF, optionally draws a header image from the Resources/Images folder, loads a custom TrueType font from the Resources/Fonts folder, writes text content to the page, and saves the result as sample.pdf in wwwroot.
private void CreatePdf()
{
try
{
// 1. Create DsPdf document
var doc = new GcPdfDocument();
// 2. Add page and get graphics
var page = doc.Pages.Add();
var g = page.Graphics;
// 3. Optional header image from Resources/Images
var imagePath = Path.Combine("Resources", "Images", "myheader.jpg");
var rc = page.Bounds;
float textTop;
if (System.IO.File.Exists(imagePath))
{
GcImage img = GcImage.FromFile(imagePath);
rc.Height *= 0.35f;
g.DrawImage(img, rc, null, ImageAlign.StretchImage);
textTop = rc.Bottom + 12;
}
else
{
textTop = 72;
}
// 4. Load custom font from Resources/Fonts, or fall back to Helvetica
var fontPath = Path.Combine("Resources", "Fonts", "OpenSans-Regular.ttf");
GcFont bodyFont;
if (System.IO.File.Exists(fontPath))
{
bodyFont = GcFont.FromFile(fontPath);
}
else
{
bodyFont = StandardFonts.Helvetica;
}
var headingFormat = new TextFormat
{
Font = bodyFont,
FontSize = 20,
ForeColor = Color.Black
};
var textFormat = new TextFormat
{
Font = bodyFont,
FontSize = 12,
ForeColor = Color.Black
};
// 5. Build the text layout
var tl = g.CreateTextLayout();
tl.MaxWidth = page.Size.Width - 72 * 2;
tl.AppendLine("Document Solutions for PDF (DsPdf)", headingFormat);
tl.AppendLine("");
tl.AppendLine(
"This PDF includes a header image and a custom font loaded from Resources. " +
"It follows the same layout style as the original marketing blog sample.",
textFormat);
tl.AppendLine("");
tl.AppendLine("Features:", textFormat);
tl.AppendLine("• Load header branding images", textFormat);
tl.AppendLine("• Use custom TTF fonts", textFormat);
tl.AppendLine("• Create rich PDF layouts in ASP.NET Core", textFormat);
tl.PerformLayout(true);
// 6. Draw the text beneath the header area
g.DrawTextLayout(tl, new PointF(72, textTop));
// 7. Save the document into wwwroot/sample.pdf
Directory.CreateDirectory(_environment.WebRootPath);
var outputPath = Path.Combine(_environment.WebRootPath, "sample.pdf");
using var fs = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
doc.Save(fs);
_logger.LogInformation("PDF created at {Path}", outputPath);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating PDF.");
}
}When the application runs, the PDF is generated on the server and saved as wwwroot/sample.pdf, making it available to the browser as a static file.

Next, install the JavaScript PDF Viewer package so the generated PDF can be displayed in the browser.
Open the Package Manager Console in Visual Studio from Tools > NuGet Package Manager > Package Manager Console, then run the following command:
npm install @mescius/dspdfviewerAfter installation, the viewer files are available in:
node_modules/@mescius/dspdfviewerCopy the dspdfviewer folder into the following location so it can be served by the ASP.NET Core application:
wwwroot/lib/dspdfviewerThis makes the viewer JavaScript and worker files available to your Razor Pages.

Now that the PDF is generated and the viewer files are available in wwwroot, update Index.cshtml to display the PDF in the browser.
Open Pages/Index.cshtml and replace the default Razor markup with the following code:
@page
@model CreatePdf_DocSol.Pages.IndexModel
@{
ViewData["Title"] = "Home page";
}
<h2>PDF Viewer</h2>
<div id="root" style="height:600px; width:100%;"></div>
@section Scripts {
<script src="/lib/dspdfviewer/dspdfviewer.js"></script>
<script>
var viewer = new DsPdfViewer("#root", {
workerSrc: "/lib/dspdfviewer/dspdfviewer.worker.js"
});
viewer.addDefaultPanels();
viewer.open("sample.pdf");
</script>
}The viewer is initialized inside the #root element. The workerSrc option points to the viewer worker file, addDefaultPanels() adds the standard toolbar and navigation panels, and open() loads the generated sample.pdf file.
When you run the application, the PDF generated on the server will be displayed in DsPdfViewer.

DsPdfViewer can do more than display PDFs. When paired with the Document Solutions SupportApi, it can also enable advanced client-side editing features such as annotations, form editing, signatures, redaction, page organization, and saving modified PDF files.
SupportApi is a server-side component that works with DsPdfViewer to process editing operations. It allows users to modify PDFs directly in the browser while the server handles document processing, saving, and validation.
To connect DsPdfViewer to SupportApi, configure the supportApi option when initializing the viewer:
var viewer = new DsPdfViewer("#root", {
workerSrc: "/lib/dspdfviewer/dspdfviewer.worker.js",
supportApi: {
apiUrl: "https://localhost:5001/api/pdf-viewer",
token: "support-api-demo-net-core-token-2021",
webSocketUrl: false
}
});
viewer.addDefaultPanels();
viewer.open("sample.pdf");The exact apiUrl and token values should match your SupportApi configuration.
Annotations are useful for reviewing and collaborating on PDF documents. With SupportApi enabled, DsPdfViewer allows users to add, edit, and remove annotations directly in the browser.
For example, users can highlight text, add comments, draw shapes, mark corrections, or use circle annotations to call attention to specific areas of a document.

This makes DsPdfViewer useful for workflows that involve document review, feedback, approval, and collaboration.
DsPdfViewer also includes page management features when SupportApi is enabled. Users can insert pages, delete pages, duplicate pages, reorder pages, and combine document content directly in the browser.

These tools are helpful when building applications that require users to restructure PDFs after they have been generated, uploaded, or reviewed.
Can I generate PDFs and display them in the same ASP.NET Core application?
Yes. DsPdf can generate PDF files on the server, and DsPdfViewer can display those files in the browser. In this tutorial, the generated file is saved to wwwroot/sample.pdf and loaded with viewer.open("sample.pdf").
Why save the generated PDF to the wwwroot folder?
The wwwroot folder is ASP.NET Core’s default location for static files. Saving the generated PDF there makes it accessible to the client-side viewer through a browser-friendly URL.
Do I need DsPdfViewer to generate PDFs?
No. DsPdf is used for server-side PDF generation and manipulation. DsPdfViewer is used to view and interact with PDF files in the browser.
Do I need SupportApi for basic PDF viewing?
No. Basic PDF viewing, navigation, zooming, and searching can be handled by DsPdfViewer in the browser. SupportApi is needed for advanced editing workflows such as annotations, form editing, signatures, redaction, page organization, and saving modified PDFs.
Can this approach be used with other ASP.NET Core project types?
Yes. Although this tutorial uses Razor Pages, the same general workflow applies to MVC and Web API projects: generate or provide the PDF on the server, make it accessible through a URL, and load it in DsPdfViewer on the client.