IronPDF Tutorials .NET Core PDF Generating Convert HTML to PDF in .NET Core: End-to-End Guide for URLs, Razor Views, Security & Docker ByJacob Mellor June 27, 2020 Updated July 13, 2025 Share: Generating high-fidelity PDFs directly from HTML is a routine requirement in modern .NET applications—reports, invoices, and tickets all need pixel-perfect output that matches the web UI. IronPDF streamlines this workflow by exposing a single C# API for rendering HTML, Razor views, and full websites into standards-compliant PDF documents. By the end of this guide a developer will be able to convert URLs, raw HTML, or MVC views in an ASP.NET Core project, and deploy the same code to Windows, Linux, Docker, or serverless environments. View the IronPDF YouTube Playlist TipsFor layout issues, IronPDF ships a headless-Chrome debugger that helps diagnose CSS, JavaScript, and media-query quirks before the PDF is rendered. Review the dedicated pixel-perfect HTML-to-PDF guide for deep-dive techniques. How to Convert HTML to PDF in .NET Core Install the IronPdf NuGet package Convert a website URL with RenderUrlAsPdf Render raw HTML via RenderHtmlAsPdf Export an MVC view to PDF Tune paper size, margins, headers, and footers Quick-Start Checklist Install – Install-Package IronPdf Render a URL – ChromePdfRenderer.RenderUrlAsPdf() Render raw HTML – ChromePdfRenderer.RenderHtmlAsPdf() Export a Razor view – ChromePdfRenderer.RenderHtmlAsPdfAsync() Fine-tune output – leverage ChromePdfRenderer.RenderingOptions What This Tutorial Covers URL, HTML string, and Razor view conversion Paper, margin, and media-type configuration Cross-platform deployment (Windows, Linux, Docker) Post-processing: merge, watermark, password-protect, and digitally sign PDFs End-to-end sample: ticket-booking MVC app Get Started with IronPDF Start using IronPDF in your project today with a free trial. First Step: Start for Free How do I install the PDF library in .NET Core? Installing the library is a one-liner in any .NET 8 project and remains forward-compatible with .NET 9 preview and the upcoming .NET 10 release. Use NuGet’s Package Manager Console and the package manager will resolve every dependency automatically for Windows, Linux, Docker, and serverless targets. PM> Install-Package IronPdf # .NET 8 LTS and higher PM> Install-Package IronPdf # .NET 8 LTS and higher SHELL Please noteNeed CLI? The same command works with dotnet add package IronPdf inside your project folder. Once installed, confirm everything is wired up by converting any public URL: // Program.cs — .NET 8 LTS using IronPdf; var renderer = new ChromePdfRenderer(); // Render a live website to PDF using PdfDocument pdf = renderer.RenderUrlAsPdf("https://example.com"); // Persist to disk pdf.SaveAs("website-snapshot.pdf"); // Program.cs — .NET 8 LTS using IronPdf; var renderer = new ChromePdfRenderer(); // Render a live website to PDF using PdfDocument pdf = renderer.RenderUrlAsPdf("https://example.com"); // Persist to disk pdf.SaveAs("website-snapshot.pdf"); ' Program.cs — .NET 8 LTS Imports IronPdf Private renderer = New ChromePdfRenderer() ' Render a live website to PDF Private PdfDocument As using ' Persist to disk pdf.SaveAs("website-snapshot.pdf") $vbLabelText $csharpLabel How it works ChromePdfRenderer spins up a sandboxed Chromium instance under the hood--no separate Chrome install is required. RenderUrlAsPdf captures the fully rendered DOM, including JavaScript-driven content, CSS media queries, and fonts. The resulting PdfDocument exposes helper methods for merging, password-protecting, or digitally signing the output--capabilities covered later in this tutorial. For more detail on deployment nuances (Azure App Service, AWS Lambda, on-prem Linux), see the dedicated installation guide and the advanced NuGet setup pages. Internal CI/CD tips for Docker and K8s clusters are covered in Docker deployment best practices. How can a .NET Core service convert a live website URL to PDF? A single call to RenderUrlAsPdf is enough: pass any publicly reachable URL and IronPDF returns a fully rendered, standards-compliant PDF. The code below targets .NET 8 LTS and compiles unchanged on .NET 9 preview as well as the forthcoming .NET 10 release in 2025. Step-by-step example // Program.cs — .NET 8 LTS-compatible using IronPdf; // 1. Activate a license (or trial key) IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; // 2. Create a reusable renderer instance var renderer = new ChromePdfRenderer { RenderingOptions = { // Force A4 portrait output and apply @media print styles PaperSize = PdfPaperSize.A4, CssMediaType = PdfCssMediaType.Print } }; // 3. Convert Microsoft Docs home page to PDF using PdfDocument pdf = renderer.RenderUrlAsPdf("https://learn.microsoft.com/"); // 4. Save the PDF or stream it from a Web API pdf.SaveAs("docs-offline-copy.pdf"); // Program.cs — .NET 8 LTS-compatible using IronPdf; // 1. Activate a license (or trial key) IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; // 2. Create a reusable renderer instance var renderer = new ChromePdfRenderer { RenderingOptions = { // Force A4 portrait output and apply @media print styles PaperSize = PdfPaperSize.A4, CssMediaType = PdfCssMediaType.Print } }; // 3. Convert Microsoft Docs home page to PDF using PdfDocument pdf = renderer.RenderUrlAsPdf("https://learn.microsoft.com/"); // 4. Save the PDF or stream it from a Web API pdf.SaveAs("docs-offline-copy.pdf"); ' Program.cs — .NET 8 LTS-compatible Imports IronPdf ' 1. Activate a license (or trial key) IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY" ' 2. Create a reusable renderer instance Dim renderer = New ChromePdfRenderer With { .RenderingOptions = { PaperSize = PdfPaperSize.A4, CssMediaType = PdfCssMediaType.Print } } ' 3. Convert Microsoft Docs home page to PDF Using pdf As PdfDocument = renderer.RenderUrlAsPdf("https://learn.microsoft.com/") ' 4. Save the PDF or stream it from a Web API pdf.SaveAs("docs-offline-copy.pdf") End Using $vbLabelText $csharpLabel Why it works ChromePdfRenderer spins up a sandboxed Chromium instance--no system Chrome dependency, keeping Docker images slim. RenderUrlAsPdf waits for the DOM and JavaScript to finish before snapshotting, so single-page apps render correctly . Setting CssMediaType to Print tells the engine to use print-specific rules, matching a browser's Print → Save as PDF output. The resulting PdfDocument can be encrypted, digitally signed, merged, or rasterized--capabilities covered in later sections. TipsPixel-perfect debugging: enable renderer.LoggingOptions.DebugMode = true and follow the headless-Chrome debug guide to inspect live DevTools during rendering. Related resources API reference – ChromePdfRenderer.RenderUrlAsPdf API reference – PdfDocument.SaveAs Tutorial – Deploy IronPDF in Docker containers How do I convert raw HTML into a PDF in .NET Core? Passing an HTML string—or a Razor view’s rendered markup—to ChromePdfRenderer.RenderHtmlAsPdf instantly produces a standards-compliant PDF. The method spins up IronPDF’s embedded Chromium engine, so no external browser installation or WebView dependency is required. The same code shown below compiles on .NET 8 LTS today and remains forward-compatible with .NET 9 and the scheduled .NET 10 release in November 2025. Example — generate a PDF from an HTML fragment // Program.cs — compatible with .NET 8 and newer using IronPdf; // Sample HTML fragment (could also be read from a file, Razor view, or CMS) const string html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Quarterly Report</title> <style> body { font-family:'Segoe UI', sans-serif; margin:1.2rem; } header { margin-bottom:2rem; } h1 { color:#3056d3; } table { width:100%; border-collapse:collapse; margin-top:1rem; } th,td { border:1px solid #ddd; padding:0.5rem; text-align:right; } tr:nth-child(even){ background-color:#f8f9fa; } </style> </head> <body> <header><h1>Q2 Revenue Summary</h1></header> <table> <thead><tr><th>Product</th><th>Revenue ($)</th></tr></thead> <tbody> <tr><td>IronPDF for .NET</td><td>1,200,000</td></tr> <tr><td>IronOCR for .NET</td><td>890,000</td></tr> <tr><td>IronXL for .NET</td><td>610,000</td></tr> </tbody> </table> </body> </html> """; // 1. Create a renderer once and reuse it across conversions var renderer = new ChromePdfRenderer { RenderingOptions = { PaperSize = PdfPaperSize.A4, // ISO-standard paper size PaperOrientation = PdfPaperOrientation.Portrait, CssMediaType = PdfCssMediaType.Screen, // Respect on-screen CSS RenderDelay = 100, // Wait 100 ms for JS/animations FallbackEncoding = "utf-8" // Handle non-ASCII correctly } }; // 2. Render the HTML fragment using PdfDocument pdf = renderer.RenderHtmlAsPdf(html); // 3. Persist to disk or return via ASP.NET Core FileStreamResult pdf.SaveAs("q2-report.pdf"); // Program.cs — compatible with .NET 8 and newer using IronPdf; // Sample HTML fragment (could also be read from a file, Razor view, or CMS) const string html = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Quarterly Report</title> <style> body { font-family:'Segoe UI', sans-serif; margin:1.2rem; } header { margin-bottom:2rem; } h1 { color:#3056d3; } table { width:100%; border-collapse:collapse; margin-top:1rem; } th,td { border:1px solid #ddd; padding:0.5rem; text-align:right; } tr:nth-child(even){ background-color:#f8f9fa; } </style> </head> <body> <header><h1>Q2 Revenue Summary</h1></header> <table> <thead><tr><th>Product</th><th>Revenue ($)</th></tr></thead> <tbody> <tr><td>IronPDF for .NET</td><td>1,200,000</td></tr> <tr><td>IronOCR for .NET</td><td>890,000</td></tr> <tr><td>IronXL for .NET</td><td>610,000</td></tr> </tbody> </table> </body> </html> """; // 1. Create a renderer once and reuse it across conversions var renderer = new ChromePdfRenderer { RenderingOptions = { PaperSize = PdfPaperSize.A4, // ISO-standard paper size PaperOrientation = PdfPaperOrientation.Portrait, CssMediaType = PdfCssMediaType.Screen, // Respect on-screen CSS RenderDelay = 100, // Wait 100 ms for JS/animations FallbackEncoding = "utf-8" // Handle non-ASCII correctly } }; // 2. Render the HTML fragment using PdfDocument pdf = renderer.RenderHtmlAsPdf(html); // 3. Persist to disk or return via ASP.NET Core FileStreamResult pdf.SaveAs("q2-report.pdf"); ' Program.cs — compatible with .NET 8 and newer Imports IronPdf ' Sample HTML fragment (could also be read from a file, Razor view, or CMS) Private Const html As String = "<!DOCTYPE html> <html lang=""en""> <head> <meta charset=""utf-8""> <title>Quarterly Report</title> <style> body { font-family:'Segoe UI', sans-serif; margin:1.2rem; } header { margin-bottom:2rem; } h1 { color:#3056d3; } table { width:100%; border-collapse:collapse; margin-top:1rem; } th,td { border:1px solid #ddd; padding:0.5rem; text-align:right; } tr:nth-child(even){ background-color:#f8f9fa; } </style> </head> <body> <header><h1>Q2 Revenue Summary</h1></header> <table> <thead><tr><th>Product</th><th>Revenue ($)</th></tr></thead> <tbody> <tr><td>IronPDF for .NET</td><td>1,200,000</td></tr> <tr><td>IronOCR for .NET</td><td>890,000</td></tr> <tr><td>IronXL for .NET</td><td>610,000</td></tr> </tbody> </table> </body> </html>" ' 1. Create a renderer once and reuse it across conversions Private renderer = New ChromePdfRenderer With { .RenderingOptions = { PaperSize = PdfPaperSize.A4, PaperOrientation = PdfPaperOrientation.Portrait, CssMediaType = PdfCssMediaType.Screen, RenderDelay = 100, FallbackEncoding = "utf-8" } } ' 2. Render the HTML fragment Private PdfDocument As using ' 3. Persist to disk or return via ASP.NET Core FileStreamResult pdf.SaveAs("q2-report.pdf") $vbLabelText $csharpLabel What the code demonstrates Embedded Chromium -- IronPDF bundles the Chromium engine, guaranteeing HTML5, CSS3, and JavaScript parity with modern browsers. Single dependency -- A lightweight NuGet install covers Windows, Linux, Docker, and Azure/AWS without extra system libraries. Rendering options -- PaperSize, CssMediaType, and RenderDelay mirror browser print settings so PDFs match on-screen layouts. Future-proof targeting -- The API surface is the same across .NET 8, .NET 9 STS, and the upcoming .NET 10, so long-term maintenance is minimal. Post-processing hooks -- PdfDocument exposes helpers for merging, password protection, and digital signatures--each covered later in this guide. Further reading: see the step-by-step HTML-string-to-PDF tutorial and the full ChromePdfRenderer API documentation. How can an ASP .NET Core MVC view be exported to PDF? IronPDF renders a fully-processed Razor view ( .cshtml ) the same way a browser would and streams the result as a PdfDocument. The workflow below keeps controller logic clean, requires no browser plugins, and works on .NET 8 LTS, .NET 9 preview, and the scheduled .NET 10 release in November 2025. End-to-end controller example // TicketsController.cs — .NET 8 LTS / MVC using IronPdf; using Microsoft.AspNetCore.Mvc; using YourApp.Models; // TicketViewModel public class TicketsController : Controller { private readonly ChromePdfRenderer _renderer; public TicketsController() { _renderer = new ChromePdfRenderer { RenderingOptions = { PaperSize = PdfPaperSize.A5, // Compact ticket size PaperOrientation = PdfPaperOrientation.Portrait, FitToPaperWidth = true, CssMediaType = PdfCssMediaType.Print, Margins = new PdfMargins(5, 10, 5, 10) // mm } }; } // GET /Tickets/Print/42 public async Task<IActionResult> Print(int id) { TicketViewModel vm = await _service.GetTicketAsync(id); // 1. Render the Razor view to an HTML string string html = await RazorTemplateEngine.RenderViewAsync( HttpContext, "~/Views/Tickets/Print.cshtml", vm); // 2. Convert HTML → PDF using PdfDocument pdf = _renderer.RenderHtmlAsPdf(html); // 3. Stream back as a file return File(pdf.BinaryData, "application/pdf", $"ticket-{id}.pdf"); } } // TicketsController.cs — .NET 8 LTS / MVC using IronPdf; using Microsoft.AspNetCore.Mvc; using YourApp.Models; // TicketViewModel public class TicketsController : Controller { private readonly ChromePdfRenderer _renderer; public TicketsController() { _renderer = new ChromePdfRenderer { RenderingOptions = { PaperSize = PdfPaperSize.A5, // Compact ticket size PaperOrientation = PdfPaperOrientation.Portrait, FitToPaperWidth = true, CssMediaType = PdfCssMediaType.Print, Margins = new PdfMargins(5, 10, 5, 10) // mm } }; } // GET /Tickets/Print/42 public async Task<IActionResult> Print(int id) { TicketViewModel vm = await _service.GetTicketAsync(id); // 1. Render the Razor view to an HTML string string html = await RazorTemplateEngine.RenderViewAsync( HttpContext, "~/Views/Tickets/Print.cshtml", vm); // 2. Convert HTML → PDF using PdfDocument pdf = _renderer.RenderHtmlAsPdf(html); // 3. Stream back as a file return File(pdf.BinaryData, "application/pdf", $"ticket-{id}.pdf"); } } ' TicketsController.cs — .NET 8 LTS / MVC Imports IronPdf Imports Microsoft.AspNetCore.Mvc Imports YourApp.Models ' TicketViewModel Public Class TicketsController Inherits Controller Private ReadOnly _renderer As ChromePdfRenderer Public Sub New() _renderer = New ChromePdfRenderer With { .RenderingOptions = { PaperSize = PdfPaperSize.A5, PaperOrientation = PdfPaperOrientation.Portrait, FitToPaperWidth = True, CssMediaType = PdfCssMediaType.Print, Margins = New PdfMargins(5, 10, 5, 10) } } End Sub ' GET /Tickets/Print/42 Public Async Function Print(ByVal id As Integer) As Task(Of IActionResult) Dim vm As TicketViewModel = Await _service.GetTicketAsync(id) ' 1. Render the Razor view to an HTML string Dim html As String = Await RazorTemplateEngine.RenderViewAsync(HttpContext, "~/Views/Tickets/Print.cshtml", vm) ' 2. Convert HTML → PDF Using pdf As PdfDocument = _renderer.RenderHtmlAsPdf(html) ' 3. Stream back as a file Return File(pdf.BinaryData, "application/pdf", $"ticket-{id}.pdf") End Using End Function End Class $vbLabelText $csharpLabel What this code illustrates No temporary files -- the Razor view is rendered in-memory, then passed directly to RenderHtmlAsPdf, avoiding disk I/O and temp-folder race conditions. Ticket-sized output -- PaperSize = A5 and narrow margins keep print-at-home tickets compact. Consistent print styles -- CssMediaType = Print applies the same @media print CSS rules that browsers use. Binary streaming -- pdf.BinaryData streams the document without touching the file-system; ideal for API endpoints and Lambda functions. Re-usable renderer -- ChromePdfRenderer is instantiated once per controller, then reused, minimising process-spawn overhead. Paper & Orientation PaperSize, PaperOrientation, FitToPaperWidth Margins & Headers / Footers Margins, Header, Footer, Watermark Next step: add encryption, digital signatures, or merge multiple tickets into a single file. See the merge example and the digital-signature how-to. How can I fine-tune paper size, margins, headers, watermarks, and security before rendering? IronPDF exposes a single ChromePdfRenderOptions object that controls every aspect of the output—paper dimensions, orientation, headers & footers, JavaScript timing, watermarks, encryption, and digital signatures—all without extra browser plugins. Code sample — apply multiple options at once // AdvancedOptions.cs — .NET 8 compatible using IronPdf; var renderer = new ChromePdfRenderer(); // Configure everything in one place renderer.RenderingOptions = new ChromePdfRenderOptions { // 1. Page layout PaperSize = PdfPaperSize.A4, // ISO size PaperOrientation = PdfPaperOrientation.Portrait, Margins = new PdfMargins { Top = 20, Bottom = 25, Left = 15, Right = 15 }, // mm // 2. Timing & media CssMediaType = PdfCssMediaType.Print, // Respect @media print EnableJavaScript = true, RenderDelay = 200, // Wait 200 ms for animations // 3. Headers & footers (HTML gives full design freedom) HtmlHeader = "<header style='font:14px Segoe UI'>Invoice — {{date}}</header>", HtmlFooter = "<footer style='text-align:right;font-size:10px'>Page {{page}} / {{total-pages}}</footer>", // 4. Watermark Watermark = new HtmlStamp { HtmlTemplate = "<div style='font-size:50px;color:#cccccc;opacity:0.3;'>CONFIDENTIAL</div>", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }, // 5. Security SecurityOptions = new PdfSecurityOptions { OwnerPassword = "StrongOwnerPwd!", UserPassword = "ReadOnly", AllowUserPrinting = false, AllowUserCopyPasteContent = false } }; // Render any HTML using PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Advanced Options Demo</h1>"); // Digitally sign with a PFX certificate (optional) pdf.SignAndStamp("./certs/company.pfx", "Iron Software", "Bangkok", "Approval"); // Save pdf.SaveAs("advanced-options-demo.pdf"); // AdvancedOptions.cs — .NET 8 compatible using IronPdf; var renderer = new ChromePdfRenderer(); // Configure everything in one place renderer.RenderingOptions = new ChromePdfRenderOptions { // 1. Page layout PaperSize = PdfPaperSize.A4, // ISO size PaperOrientation = PdfPaperOrientation.Portrait, Margins = new PdfMargins { Top = 20, Bottom = 25, Left = 15, Right = 15 }, // mm // 2. Timing & media CssMediaType = PdfCssMediaType.Print, // Respect @media print EnableJavaScript = true, RenderDelay = 200, // Wait 200 ms for animations // 3. Headers & footers (HTML gives full design freedom) HtmlHeader = "<header style='font:14px Segoe UI'>Invoice — {{date}}</header>", HtmlFooter = "<footer style='text-align:right;font-size:10px'>Page {{page}} / {{total-pages}}</footer>", // 4. Watermark Watermark = new HtmlStamp { HtmlTemplate = "<div style='font-size:50px;color:#cccccc;opacity:0.3;'>CONFIDENTIAL</div>", VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }, // 5. Security SecurityOptions = new PdfSecurityOptions { OwnerPassword = "StrongOwnerPwd!", UserPassword = "ReadOnly", AllowUserPrinting = false, AllowUserCopyPasteContent = false } }; // Render any HTML using PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Advanced Options Demo</h1>"); // Digitally sign with a PFX certificate (optional) pdf.SignAndStamp("./certs/company.pfx", "Iron Software", "Bangkok", "Approval"); // Save pdf.SaveAs("advanced-options-demo.pdf"); ' AdvancedOptions.cs — .NET 8 compatible Imports IronPdf Private renderer = New ChromePdfRenderer() ' Configure everything in one place renderer.RenderingOptions = New ChromePdfRenderOptions With { .PaperSize = PdfPaperSize.A4, .PaperOrientation = PdfPaperOrientation.Portrait, .Margins = New PdfMargins With { .Top = 20, .Bottom = 25, .Left = 15, .Right = 15 }, .CssMediaType = PdfCssMediaType.Print, .EnableJavaScript = True, .RenderDelay = 200, .HtmlHeader = "<header style='font:14px Segoe UI'>Invoice — {{date}}</header>", .HtmlFooter = "<footer style='text-align:right;font-size:10px'>Page {{page}} / {{total-pages}}</footer>", .Watermark = New HtmlStamp With { .HtmlTemplate = "<div style='font-size:50px;color:#cccccc;opacity:0.3;'>CONFIDENTIAL</div>", .VerticalAlignment = VerticalAlignment.Center, .HorizontalAlignment = HorizontalAlignment.Center }, .SecurityOptions = New PdfSecurityOptions With { .OwnerPassword = "StrongOwnerPwd!", .UserPassword = "ReadOnly", .AllowUserPrinting = False, .AllowUserCopyPasteContent = False } } ' Render any HTML Using pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Advanced Options Demo</h1>") ' Digitally sign with a PFX certificate (optional) pdf.SignAndStamp("./certs/company.pfx", "Iron Software", "Bangkok", "Approval") ' Save pdf.SaveAs("advanced-options-demo.pdf") End Using $vbLabelText $csharpLabel Why these options matter PaperSize, Margins, and CssMediaType mirror a browser's print dialog so on-screen layouts and the PDF remain identical on Windows, Linux, and Docker. HTML headers and footers support Razor tokens, CSS, and JavaScript--handy for dynamic page numbers or branding. HtmlStamp lets a single line create branded watermarks with full HTML + CSS control. Security options enable 128-bit encryption, owner/user passwords, and granular permissions without third-party tools. Digital signatures add a cryptographic seal directly in code, maintaining legal authenticity and tamper evidence. Extraction helpers such as ExtractAllText and ExtractAllImages reverse the process when analysis is required. Quick reference — Popular settings Page Layout & Media PaperSize, PaperOrientation, Margins, CssMediaType, RenderDelay Headers & Footers HtmlHeader, HtmlFooter, dynamic Razor placeholders, page-number tokens Watermarking Watermark, HtmlStamp, opacity, alignment Encryption & Signatures SecurityOptions, SignAndStamp, owner / user passwords, 128-bit AES, certificate sealing Next tasks: merge multiple PDFs, extract text & images, and deploy to Docker or serverless. Continue to the deployment section to ensure cross-platform parity. How can I deploy PDF-generation code to Docker on Linux and Windows? IronPDF ships as a single self-contained NuGet package, so containerizing an ASP.NET Core (or console) app is straightforward on both Windows and Linux. The key is to copy the published binaries into a slim runtime image and, on Linux, add the two native libraries IronPDF requires (libnss3 and libatk1.0-0). Multi-stage Dockerfile (Ubuntu 22.04) Please noteWhy multi-stage? The SDK image (stage 1) compiles the project; the final runtime image (stage 2) stays lean—< 120 MB—because build tools are discarded. ####### ---------- stage 1 ---------- FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["MyPdfApp.csproj", "."] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish ####### ---------- stage 2 ---------- FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy ######## Install two native libs required by Chromium RUN apt-get update && \ apt-get install -y --no-install-recommends libnss3 libatk1.0-0 && \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "MyPdfApp.dll"] Please noteWindows containers? Replace the second stage with mcr.microsoft.com/dotnet/aspnet:8.0-windowsservercore-ltsc2022—no additional packages are needed because Chromium DLLs are bundled. End-to-end validation script docker build -t pdf-demo . docker run --rm -p 8080:80 pdf-demo ######### ↳ Navigate to http://localhost:8080/api/pdf?url=https://example.com docker build -t pdf-demo . docker run --rm -p 8080:80 pdf-demo ######### ↳ Navigate to http://localhost:8080/api/pdf?url=https://example.com SHELL The API action internally calls ChromePdfRenderer.RenderUrlAsPdf just like in Section 2. IronPDF spins up its sandboxed Chromium process inside the container—no X server is required because it renders headlessly. Memory footprint stays under 200 MB even during large renders. TipsTroubleshooting tip: If the container logs show a “libnss3.so not found” error, confirm both libnss3 and libatk1.0-0 are present. Alpine images are not supported because the musl C library lacks required symbols. Internal resources Tutorial – Deploy IronPDF in Docker containers How-to – Run IronPDF on Azure App Service Linux API reference – ChromePdfRenderer class How can I open, merge, watermark, and extract content from existing PDFs in .NET Core? IronPDF treats every PDF—whether generated by IronPDF, Adobe® Acrobat, or third-party tools—as a first-class PdfDocument object that can be opened, edited, secured, and re-saved without quality loss. The same API surface works on .NET 8 LTS today and compiles unchanged on the .NET 9 preview and the forthcoming .NET 10 release. Unified sample — open → merge → watermark → extract // ManipulateExistingPdf.cs — .NET 8 LTS compatible using IronPdf; using System.Linq; // Step 1: Open two existing files (password-protected PDFs are supported) PdfDocument invoice = PdfDocument.FromFile("invoice.pdf", "ReadOnly"); // open with user pwd PdfDocument tAndCs = PdfDocument.FromFile("terms.pdf"); // no pwd required // Step 2: Merge them (invoice pages first, then T&Cs) PdfDocument mergedPdf = PdfDocument.Merge(invoice, tAndCs); // 1-liner merge // Step 3: Apply a diagonal CONFIDENTIAL watermark to every page mergedPdf.ApplyStamp( "<div style='font-size:60px;color:#d9534f;opacity:0.2;transform:rotate(-45deg);" + "width:100%;text-align:center;'>CONFIDENTIAL</div>", verticalAlignment : VerticalAlignment.Center, horizontalAlignment : HorizontalAlignment.Center); // Step 4: Extract all text and the first image for audit purposes string fullText = mergedPdf.ExtractAllText(); var image = mergedPdf.ExtractAllImages().FirstOrDefault(); // Step 5: Save or stream mergedPdf.SaveAs("invoice-with-terms.pdf"); // ManipulateExistingPdf.cs — .NET 8 LTS compatible using IronPdf; using System.Linq; // Step 1: Open two existing files (password-protected PDFs are supported) PdfDocument invoice = PdfDocument.FromFile("invoice.pdf", "ReadOnly"); // open with user pwd PdfDocument tAndCs = PdfDocument.FromFile("terms.pdf"); // no pwd required // Step 2: Merge them (invoice pages first, then T&Cs) PdfDocument mergedPdf = PdfDocument.Merge(invoice, tAndCs); // 1-liner merge // Step 3: Apply a diagonal CONFIDENTIAL watermark to every page mergedPdf.ApplyStamp( "<div style='font-size:60px;color:#d9534f;opacity:0.2;transform:rotate(-45deg);" + "width:100%;text-align:center;'>CONFIDENTIAL</div>", verticalAlignment : VerticalAlignment.Center, horizontalAlignment : HorizontalAlignment.Center); // Step 4: Extract all text and the first image for audit purposes string fullText = mergedPdf.ExtractAllText(); var image = mergedPdf.ExtractAllImages().FirstOrDefault(); // Step 5: Save or stream mergedPdf.SaveAs("invoice-with-terms.pdf"); ' ManipulateExistingPdf.cs — .NET 8 LTS compatible Imports IronPdf Imports System.Linq ' Step 1: Open two existing files (password-protected PDFs are supported) Private invoice As PdfDocument = PdfDocument.FromFile("invoice.pdf", "ReadOnly") ' open with user pwd Private tAndCs As PdfDocument = PdfDocument.FromFile("terms.pdf") ' no pwd required ' Step 2: Merge them (invoice pages first, then T&Cs) Private mergedPdf As PdfDocument = PdfDocument.Merge(invoice, tAndCs) ' 1-liner merge ' Step 3: Apply a diagonal CONFIDENTIAL watermark to every page mergedPdf.ApplyStamp("<div style='font-size:60px;color:#d9534f;opacity:0.2;transform:rotate(-45deg);" & "width:100%;text-align:center;'>CONFIDENTIAL</div>", verticalAlignment := VerticalAlignment.Center, horizontalAlignment := HorizontalAlignment.Center) ' Step 4: Extract all text and the first image for audit purposes Dim fullText As String = mergedPdf.ExtractAllText() Dim image = mergedPdf.ExtractAllImages().FirstOrDefault() ' Step 5: Save or stream mergedPdf.SaveAs("invoice-with-terms.pdf") $vbLabelText $csharpLabel Why this matters Open & merge – PdfDocument.FromFile loads any standards-compliant PDF, including encrypted files, while PdfDocument.Merge concatenates an arbitrary number of documents in a single call. Watermark – ApplyStamp (alias HtmlStamp) embeds fully styled HTML/CSS overlays--logo, QR code, or diagonal text--on selected pages without rasterisation. Content extraction – ExtractAllText and ExtractAllImages pull raw UTF-8 text or binary image streams for downstream archiving or AI pipelines. Digital signatures ready – the same PdfDocument instance can be sealed with SignAndStamp, producing RFC 3161-compliant hashes aligned with ISO 32000-2 digital-signature requirements. Open standard compliance – IronPDF preserves the original PDF structure (fonts, layers, XMP metadata) so the output remains compatible with Adobe® Reader and other ISO 32000-1 viewers. Future-proof – The API avoids interop assemblies and Win32 GDI calls, so code runs unchanged on Windows, Linux, Docker, and upcoming .NET 10 serverless SKUs. Need split, rotate, or delete pages? See the page-level edit tutorial for granular operations. How can PDFs be encrypted and digitally signed in .NET Core? IronPDF secures a document in two steps: AES-based encryption (user/owner passwords + granular permissions) and X.509 digital signatures that seal the file with a cryptographic hash. Both APIs live on the same PdfDocument object, so the workflow is identical on .NET 8 LTS today and compiles unchanged on .NET 9 preview and the forthcoming .NET 10 release. Example — apply 256-bit AES, lock print rights, and add a visible signature // SecureAndSign.cs — .NET 8 LTS compatible using IronPdf; // Step 1: Load an existing PDF (or produce one with RenderHtmlAsPdf) PdfDocument pdf = PdfDocument.FromFile("financial-report.pdf"); // Step 2: Configure AES-256 encryption & permissions pdf.SecuritySettings = new PdfSecuritySettings { EncryptionAlgorithm = PdfEncryptionAlgorithm.AES256Bit, OwnerPassword = "IronAdmin!2025", UserPassword = "ReadOnly", AllowUserPrinting = PdfPrintSecurity.Disabled, AllowUserCopyPasteContent = false, AllowUserAnnotations = false }; // Step 3: Digitally sign with a PFX certificate pdf.SignAndStamp( certificatePath : "./certs/ironsoftware.pfx", authority : "Iron Software Ltd.", location : "Chicago, IL", reason : "Final approval" ); // Step 4: Persist or stream pdf.SaveAs("financial-report-secured-signed.pdf"); // SecureAndSign.cs — .NET 8 LTS compatible using IronPdf; // Step 1: Load an existing PDF (or produce one with RenderHtmlAsPdf) PdfDocument pdf = PdfDocument.FromFile("financial-report.pdf"); // Step 2: Configure AES-256 encryption & permissions pdf.SecuritySettings = new PdfSecuritySettings { EncryptionAlgorithm = PdfEncryptionAlgorithm.AES256Bit, OwnerPassword = "IronAdmin!2025", UserPassword = "ReadOnly", AllowUserPrinting = PdfPrintSecurity.Disabled, AllowUserCopyPasteContent = false, AllowUserAnnotations = false }; // Step 3: Digitally sign with a PFX certificate pdf.SignAndStamp( certificatePath : "./certs/ironsoftware.pfx", authority : "Iron Software Ltd.", location : "Chicago, IL", reason : "Final approval" ); // Step 4: Persist or stream pdf.SaveAs("financial-report-secured-signed.pdf"); ' SecureAndSign.cs — .NET 8 LTS compatible Imports IronPdf ' Step 1: Load an existing PDF (or produce one with RenderHtmlAsPdf) Private pdf As PdfDocument = PdfDocument.FromFile("financial-report.pdf") ' Step 2: Configure AES-256 encryption & permissions pdf.SecuritySettings = New PdfSecuritySettings With { .EncryptionAlgorithm = PdfEncryptionAlgorithm.AES256Bit, .OwnerPassword = "IronAdmin!2025", .UserPassword = "ReadOnly", .AllowUserPrinting = PdfPrintSecurity.Disabled, .AllowUserCopyPasteContent = False, .AllowUserAnnotations = False } ' Step 3: Digitally sign with a PFX certificate pdf.SignAndStamp(certificatePath := "./certs/ironsoftware.pfx", authority := "Iron Software Ltd.", location := "Chicago, IL", reason := "Final approval") ' Step 4: Persist or stream pdf.SaveAs("financial-report-secured-signed.pdf") $vbLabelText $csharpLabel Behind the scenes AES-256 encryption -- IronPDF wraps the payload with NIST-approved AES keys, blocking unauthorised opening, printing, or copy-paste. Permissions granularity -- properties such as AllowUserPrinting and AllowUserFormData toggle per-action rights; an owner password is required for any restriction to take effect. Digital signatures -- SignAndStamp embeds an RFC 3161 timestamp and certificate chain, creating tamper-evident hashes recognised by Adobe® Acrobat and other ISO 32000-2 viewers. One-stop API -- both encryption and signing modify the same PdfDocument instance, avoiding multiple file passes and preserving internal fonts, layers, and metadata. TipsTroubleshooting tip: if Adobe Reader reports “invalid signature,” ensure the PFX contains a trusted root certificate and the reason/location strings are ASCII-clean. Core security settings Encryption & Passwords PdfSecuritySettings → OwnerPassword, UserPassword, EncryptionAlgorithm, AllowUserPrinting Digital Signatures PdfDocument.SignAndStamp — PFX path, authority, location, reason, timestamp Internal resources for deeper dives Tutorial – Password-protect a PDF Example – Digitally sign a PDF API reference – PdfSecuritySettings How can HTML-to-PDF performance be optimized and scaled in .NET Core? IronPDF’s Chromium engine already renders most pages in < 1 s on modern hardware, but throughput can be multiplied by batching renders, enabling multi-threading, and trimming headless-Chrome overhead. The tips below apply equally to all .NET versions. 1. Batch renders on a background thread pool // BatchRender.cs — Thread-safe on .NET 8+ using IronPdf; using System.Threading.Tasks; var htmlSources = Directory.GetFiles("./html", "*.html"); var renderer = new ChromePdfRenderer(); // reuse 1 instance Parallel.ForEach(htmlSources, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, file => { string html = File.ReadAllText(file); using PdfDocument pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs(Path.ChangeExtension(file, ".pdf")); }); // BatchRender.cs — Thread-safe on .NET 8+ using IronPdf; using System.Threading.Tasks; var htmlSources = Directory.GetFiles("./html", "*.html"); var renderer = new ChromePdfRenderer(); // reuse 1 instance Parallel.ForEach(htmlSources, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, file => { string html = File.ReadAllText(file); using PdfDocument pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs(Path.ChangeExtension(file, ".pdf")); }); ' BatchRender.cs — Thread-safe on .NET 8+ Imports IronPdf Imports System.Threading.Tasks Private htmlSources = Directory.GetFiles("./html", "*.html") Private renderer = New ChromePdfRenderer() ' reuse 1 instance Parallel.ForEach(htmlSources, New ParallelOptions With {.MaxDegreeOfParallelism = Environment.ProcessorCount}, Sub(file) Dim html As String = File.ReadAllText(file) Using pdf As PdfDocument = renderer.RenderHtmlAsPdf(html) pdf.SaveAs(Path.ChangeExtension(file, ".pdf")) End Using End Sub) $vbLabelText $csharpLabel ChromePdfRenderer is thread-safe; a single instance may serve dozens of concurrent tasks without deadlocks. Parallel.ForEach saturates every CPU core; typical servers see 4–6× throughput gains compared with a single-thread loop. If ASP.NET requests queue up, move heavy renders to a hosted background service or message queue to keep response times low. 2. Trim headless-Chrome startup cost IronPDF ships its own Chromium build, but each render incurs a small startup tax. Pooling helps, and Linux containers must include two native libs: RUN apt-get update && \ apt-get install -y --no-install-recommends libnss3 libatk1.0-0 Missing either library manifests as a “libnss3.so not found” error in Docker logs. Recommended Chrome flags (automatically applied by IronPDF) include --disable-gpu and --no-sandbox to reduce memory and root-user issues in containers. 3. Wait for late JavaScript with RenderDelay or WaitFor Pages that animate counters or fetch data after DOMContentLoaded may need a short delay: renderer.RenderingOptions.RenderDelay = 200; // ms // OR: renderer.RenderingOptions.JavaScript = "WaitFor('window.doneLoading')"; renderer.RenderingOptions.RenderDelay = 200; // ms // OR: renderer.RenderingOptions.JavaScript = "WaitFor('window.doneLoading')"; renderer.RenderingOptions.RenderDelay = 200 ' ms ' OR: renderer.RenderingOptions.JavaScript = "WaitFor('window.doneLoading')"; $vbLabelText $csharpLabel See the dedicated WaitFor tutorial for custom promises and DOM polling. 4. Enable debug logging for one request renderer.LoggingOptions.DebugMode = true; renderer.LoggingOptions.LogsToConsole = true; renderer.LoggingOptions.LogFilePath = "./logs/ironpdf-debug.log"; renderer.LoggingOptions.DebugMode = true; renderer.LoggingOptions.LogsToConsole = true; renderer.LoggingOptions.LogFilePath = "./logs/ironpdf-debug.log"; renderer.LoggingOptions.DebugMode = True renderer.LoggingOptions.LogsToConsole = True renderer.LoggingOptions.LogFilePath = "./logs/ironpdf-debug.log" $vbLabelText $csharpLabel Live DevTools traces expose missing fonts, 404 images, and timing events without re-compiling code. 5. Reuse template PDFs instead of re-rendering For invoice runs, create a template PDF with placeholders like [[name]] and perform a text replace instead of rebuilding complex HTML. It’s 10× faster and memory-light. Quick-Tuning Checklist Multi-Thread & Async Parallel.ForEach, async/await, reuse a single ChromePdfRenderer Docker-Optimised Images Use aspnet:8.0-jammy; install libnss3 + libatk1.0-0; flags --no-sandbox, --disable-gpu JavaScript Timing RenderDelay, WaitFor(), log DevTools timeline for slow SPA hydrations Further Reading How-to – Generate PDFs with async / multithreading Troubleshooting – Performance assistance centre Example – Threaded rendering demo Where can I download a free trial, choose a license, and find expert support? {#anchor-10-resources} A 30-day trial key is issued instantly from the Start Free Trial form and unlocks every feature—including HTML-to-PDF, digital signatures, and encryption—without watermarking. After evaluating the library, pick a perpetual developer, deployment, or enterprise license; each plan includes free minor updates, dev/staging/production usage rights, and a 30-day money-back guarantee. Applying the key is a single line of code (IronPdf.License.LicenseKey = "YOUR-KEY";) and can be automated in CI/CD pipelines. Comprehensive documentation—quick-start guides, API reference, and tutorial videos—lives at the docs portal and is updated for every .NET release. Engineering questions receive one-business-day responses via live chat, email, or phone from the Chicago-based support team. Performance tuning and deployment FAQs are aggregated in the Performance Assistance Centre. Quick links Resource URL Why it matters Get a 30-day trial key https://ironpdf.com/demos/ Unlocks every feature without watermarks Licensing & pricing https://ironpdf.com/licensing/ Perpetual or subscription plans; Iron Suite bundles 10 libraries API reference https://ironpdf.com/object-reference/api/ Full class docs, e.g. ChromePdfRenderer Docs portal https://ironpdf.com/docs/ Guides, tutorials, sample projects Performance assistance https://ironpdf.com/troubleshooting/ironpdf-performance-assistance/ Optimization and scaling tips Contact support https://ironsoftware.com/contact-us/ Live chat, email, phone support Next steps Clone the sample repo that demonstrates every major feature—from MVC view rendering to AES-256 encryption. Plug the trial key into an existing solution and run the unit tests to validate cross-platform compatibility. Book a live demo with the engineering team for project-specific recommendations. With these resources in hand, any .NET team can ship pixel-perfect PDFs to production—on-prem, in Docker, or serverless—within a single sprint. Frequently Asked Questions How do I convert HTML to PDF using .NET Core? You can convert HTML to PDF in .NET Core using IronPDF library. Install the library from NuGet, create a ChromePdfRenderer instance, and use methods like RenderHtmlAsPdf to convert HTML strings or RenderUrlAsPdf to convert web pages into PDF documents. What are the steps to convert a website URL to PDF? To convert a website URL to PDF with IronPDF: 1) Install the IronPDF NuGet package, 2) Create a ChromePdfRenderer instance, 3) Use the RenderUrlAsPdf method with the target URL, and 4) Save the resulting PdfDocument using the SaveAs method. How can I convert MVC views to PDF documents? Convert MVC views to PDF by rendering the view to an HTML string using controller extensions, then passing that HTML to IronPDF's RenderHtmlAsPdf method. This approach enables generating dynamic PDFs from Razor views with model data binding. Can I work with existing PDF documents? Yes, IronPDF can open, edit, and manipulate existing PDFs. Use PdfDocument.FromFile to load documents, then perform operations like merging with AppendPdf, adding headers/footers with AddTextHeaders, or applying security settings. What PDF rendering options are available? IronPDF offers extensive rendering options through ChromePdfRenderOptions including paper size, orientation, margins, headers, footers, JavaScript execution, CSS media types, custom fonts, and page layout controls for professional document formatting. How do I deploy PDF applications with Docker? Deploy IronPDF applications in Docker by configuring Linux dependencies in your Dockerfile, setting appropriate user permissions, and enabling IronPdf.Installation.LinuxAndDockerDependenciesAutoConfig for automatic dependency management in containerized environments. How can I add digital signatures to PDFs? Add digital signatures using the PdfSignature class with certificate files (.pfx format). Use the Sign method on PdfDocument objects to apply cryptographic signatures for document authenticity and tamper detection. What security features are available for PDF files? IronPDF provides comprehensive security including password protection, user permission controls, encryption settings, and access restrictions. Configure these through the SecuritySettings property to control printing, copying, and editing permissions. Can I extract text and images from PDFs? Yes, IronPDF can extract content using ExtractAllText and ExtractAllImages methods for entire documents, or ExtractTextFromPage and ExtractImagesFromPage for specific pages, enabling data processing and content analysis workflows. How do I add watermarks to PDF documents? Add watermarks using the Watermark property with HtmlStamp objects for simple text overlays, or use the HtmlStamper class for advanced stamping with HTML content, custom positioning, rotation, and transparency effects. Jacob Mellor Chat with engineering team now Chief Technology Officer Jacob Mellor is Chief Technology Officer at Iron Software and a visionary engineer pioneering C# PDF technology. As the original developer behind Iron Software's core codebase, he has shaped the company's product architecture since its inception, transforming it alongside CEO Cameron Rimington into a 50+ person company serving NASA, Tesla, and global government agencies.Jacob holds a First-Class Honours Bachelor of Engineering (BEng) in Civil Engineering from the University of Manchester (1998–2001). After opening his first software business in London in 1999 and creating his first .NET components in 2005, he specialized in solving complex problems across the Microsoft ecosystem.His flagship IronPDF & IronSuite .NET libraries have achieved over 30 million NuGet installations globally, with his foundational code continuing to power developer tools used worldwide. With 25 years of commercial experience and 41 years of coding expertise, Jacob remains focused on driving innovation in enterprise-grade C#, Java, and Python PDF technologies while mentoring the next generation of technical leaders. Ready to Get Started? Free NuGet Download Total downloads: 14,403,271 View Licenses