Tips
For 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.

Quick-Start Checklist

  1. InstallInstall-Package IronPdf
  2. Render a URLChromePdfRenderer.RenderUrlAsPdf()
  3. Render raw HTMLChromePdfRenderer.RenderHtmlAsPdf()
  4. Export a Razor viewChromePdfRenderer.RenderHtmlAsPdfAsync()
  5. 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:
green arrow pointer


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 note
Need 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.

Tips
Pixel-perfect debugging: enable renderer.LoggingOptions.DebugMode = true and follow the headless-Chrome debug guide to inspect live DevTools during rendering.


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.

PaperSize, PaperOrientation, FitToPaperWidth

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.

PaperSize, PaperOrientation, Margins, CssMediaType, RenderDelay

HtmlHeader, HtmlFooter, dynamic Razor placeholders, page-number tokens

Watermark, HtmlStamp, opacity, alignment

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 note
Why 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 note
Windows 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.

Tips
Troubleshooting 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


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 & mergePdfDocument.FromFile loads any standards-compliant PDF, including encrypted files, while PdfDocument.Merge concatenates an arbitrary number of documents in a single call.
  • WatermarkApplyStamp (alias HtmlStamp) embeds fully styled HTML/CSS overlays--logo, QR code, or diagonal text--on selected pages without rasterisation.
  • Content extractionExtractAllText 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.

Tips
Troubleshooting 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

PdfSecuritySettingsOwnerPassword, UserPassword, EncryptionAlgorithm, AllowUserPrinting

PdfDocument.SignAndStamp — PFX path, authority, location, reason, timestamp

Internal resources for deeper dives


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

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

Parallel.ForEach, async/await, reuse a single ChromePdfRenderer

Use aspnet:8.0-jammy; install libnss3 + libatk1.0-0; flags --no-sandbox, --disable-gpu

RenderDelay, WaitFor(), log DevTools timeline for slow SPA hydrations

Further Reading


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.

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

  1. Clone the sample repo that demonstrates every major feature—from MVC view rendering to AES-256 encryption.
  2. Plug the trial key into an existing solution and run the unit tests to validate cross-platform compatibility.
  3. 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, Chief Technology Officer @ Team Iron
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.