Migrate from ActivePDF to IronPDF: (.NET Guide)
ActivePDF has been a dependable PDF toolkit for .NET developers. Since PDFTron acquired it in June 2020 and rebranded to Apryse in February 2023, ActivePDF now sits as one of several brands inside the broader Apryse portfolio. This guide offers a thorough, step-by-step migration path from ActivePDF to IronPDF—a modern, actively maintained .NET PDF library supporting .NET Framework 4.6.2 through .NET 9.
Why Consider Moving Away from ActivePDF?
ActivePDF still ships and the ActivePDF.Toolkit NuGet package continues to receive updates under Apryse, but several aspects of its design and packaging can prompt teams to evaluate alternatives.
Brand and Roadmap Considerations
ActivePDF is now one brand inside Apryse, alongside the flagship Apryse SDK. Teams that picked ActivePDF specifically for its server-side automation focus may want to weigh whether to stay on the ActivePDF SKUs or move to the broader Apryse SDK over time.
Licensing Model
ActivePDF's traditional per-server/per-core licensing can introduce friction in cloud and containerized environments where applications scale dynamically across infrastructure.
Legacy Architecture Patterns
ActivePDF's API surface reflects its COM/native origins. The OpenOutputFile/CloseOutputFile workflow and integer return codes (0 for success) require explicit lifecycle management that doesn't always align with modern C# idioms like using, exceptions, and async.
Multi-SKU Product Layout
HTML/URL-to-PDF rendering lives in the separate ActivePDF.WebGrabber product, while PDF manipulation lives in ActivePDF.Toolkit. Starting with Toolkit 10, the native libraries are no longer auto-copied to the system folder, so the constructor often needs an explicit CoreLibPath argument—a pattern that can complicate Docker, CI, and installer-less deployments.
ActivePDF vs. IronPDF: Key Differences
Before starting the migration process, understanding the fundamental differences between ActivePDF and IronPDF helps set expectations for the code changes required.
| Aspect | ActivePDF | IronPDF |
|---|---|---|
| Vendor | Apryse (formerly PDFTron, acquired ActivePDF June 2020) | Iron Software, independent |
| Product Layout | Multiple SKUs (Toolkit, WebGrabber, DocConverter, Server, Meridian) | Single IronPdf NuGet package |
| Installation | NuGet package + native runtime path (CoreLibPath since v10) |
Single NuGet package; natives bundled |
| API Pattern | Stateful (OpenOutputFile/CloseOutputFile), COM-derived |
Fluent, functional API |
| License Model | Per-server / per-core | Code-based key |
| .NET Support | .NET Framework 4.5+ / .NET Standard 1.0+ / .NET Core | Framework 4.6.2 to .NET 9 |
| Error Handling | Integer return codes (0 = success) | Standard .NET exceptions |
| Async Support | Not native | Full async/await support |
Pre-Migration Preparation
Audit Your Codebase
Before beginning migration, identify all ActivePDF usage across your solution. The real namespaces are APToolkitNET (Toolkit) and APWebGrabber (WebGrabber); a few legacy projects also reference ActivePDF.Toolkit via the COM interop assembly. Run these commands in your solution directory:
grep -r "using APToolkitNET" --include="*.cs" .
grep -r "using APWebGrabber" --include="*.cs" .
grep -r "ActivePDF" --include="*.csproj" .
grep -r "using APToolkitNET" --include="*.cs" .
grep -r "using APWebGrabber" --include="*.cs" .
grep -r "ActivePDF" --include="*.csproj" .
Document Breaking Changes
Understanding the fundamental API differences helps plan your migration strategy:
| Category | ActivePDF Behavior | IronPDF Behavior | Migration Action |
|---|---|---|---|
| Product Split | Toolkit (manipulation) + WebGrabber (HTML rendering) sold separately | Single IronPdf package |
Collapse both into one library |
| Object Model | APToolkitNET.Toolkit for PDFs, APWebGrabber.WebGrabber for HTML |
ChromePdfRenderer + PdfDocument |
Separate concerns |
| File Operations | OpenOutputFile()/CloseOutputFile() |
Direct SaveAs() |
Remove open/close calls |
| Native Runtime | CoreLibPath argument since v10 |
NuGet ships natives | Remove path configuration |
| Page Creation | NewPage() method |
Automatic from HTML | Remove page creation calls |
| Return Values | Integer error codes | Exceptions | Implement try/catch |
| Page Size Units | Points (612x792 = Letter) | Enums or millimeters | Update measurements |
Prerequisites
Ensure your environment meets these requirements:
- .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ or JetBrains Rider
- NuGet Package Manager access
- IronPDF license key (free trial available at ironpdf.com)
Step-by-Step Migration Process
Step 1: Update NuGet Packages
The package on nuget.org is ActivePDF.Toolkit (current version 11.4.4, published December 2025). HTML rendering ships separately as ActivePDF.WebGrabber. Remove the ActivePDF SKUs and install IronPDF:
# Remove ActivePDF packages
dotnet remove package ActivePDF.Toolkit
dotnet remove package ActivePDF.WebGrabber
# Install IronPDF
dotnet add package IronPdf
# Remove ActivePDF packages
dotnet remove package ActivePDF.Toolkit
dotnet remove package ActivePDF.WebGrabber
# Install IronPDF
dotnet add package IronPdf
Alternatively, via the Visual Studio Package Manager Console:
Uninstall-Package ActivePDF.Toolkit
Uninstall-Package ActivePDF.WebGrabber
Install-Package IronPdf
For projects with manual DLL references, remove the reference from your .csproj file:
<Reference Include="APToolkitNET">
<HintPath>path\to\APToolkitNET.dll</HintPath>
</Reference>
<Reference Include="APToolkitNET">
<HintPath>path\to\APToolkitNET.dll</HintPath>
</Reference>
Step 2: Configure the License Key
Add the IronPDF license key at application startup, before any PDF operations:
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Verify license status
Dim isLicensed As Boolean = IronPdf.License.IsLicensed
Step 3: Update Namespace References
Perform a global find-and-replace across your solution:
| Find | Replace With |
|---|---|
using APToolkitNET; |
using IronPdf; |
using APWebGrabber; |
using IronPdf; |
APToolkitNET.Toolkit |
ChromePdfRenderer (rendering) / PdfDocument (manipulation) |
APWebGrabber.WebGrabber |
ChromePdfRenderer |
Complete API Migration Reference
Document Creation Methods
| ActivePDF Method | IronPDF Equivalent | Notes |
|---|---|---|
new APToolkitNET.Toolkit() |
new ChromePdfRenderer() / new PdfDocument(...) |
IronPDF separates rendering from manipulation |
new Toolkit(CoreLibPath: path) |
new ChromePdfRenderer() |
NuGet ships natives—no CoreLibPath |
toolkit.OpenOutputFile(path) |
No equivalent needed | Just call SaveAs at end |
toolkit.CloseOutputFile() |
No equivalent needed | using handles cleanup |
webGrabber.URL = html; webGrabber.ConvertToPDF() |
renderer.RenderHtmlAsPdf(html) |
WebGrabber, not Toolkit |
webGrabber.URL = url; webGrabber.ConvertToPDF() |
renderer.RenderUrlAsPdf(url) |
WebGrabber, not Toolkit |
File Operations
| ActivePDF Method | IronPDF Equivalent | Notes |
|---|---|---|
toolkit.OpenInputFile(path) |
PdfDocument.FromFile(path) |
Load existing PDF |
toolkit.MergeFile(path, startPage, endPage) |
PdfDocument.Merge(pdfs) |
ActivePDF merges into the open output file in-place; IronPDF returns a new merged document |
toolkit.NumPages (property) |
pdf.PageCount |
Page count |
toolkit.GetPageText(page, 0) |
pdf.Pages[i].Text / pdf.ExtractAllText() |
Text extraction |
Page Configuration
| ActivePDF Method | IronPDF Equivalent |
|---|---|
toolkit.SetPageSize(612, 792) |
RenderingOptions.PaperSize = PdfPaperSize.Letter |
toolkit.SetOrientation("Landscape") |
RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape |
toolkit.SetMargins(t, b, l, r) |
RenderingOptions.MarginTop/Bottom/Left/Right |
Security Methods
| ActivePDF Method | IronPDF Equivalent |
|---|---|
toolkit.SetEncryption(user, owner, 128, 0) |
pdf.SecuritySettings.OwnerPassword / UserPassword |
toolkit.SetPermissions(flags) |
pdf.SecuritySettings.AllowUserXxx |
toolkit.PrintText(x, y, text) (per-page watermark) |
pdf.ApplyWatermark(html) |
Code Migration Examples
HTML to PDF Conversion
Converting HTML strings to PDF documents represents one of the most common PDF generation scenarios. Note that in ActivePDF, HTML rendering lives in the separately-licensed WebGrabber product, not Toolkit, and WebGrabber renders from a URL or file path rather than an in-memory string.
ActivePDF Implementation (WebGrabber):
// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;
class Program
{
static void Main()
{
WebGrabber wg = new WebGrabber();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
File.WriteAllText(tempHtml, htmlContent);
wg.URL = tempHtml;
wg.OutputDirectory = Directory.GetCurrentDirectory();
wg.OutputFilename = "output.pdf";
if (wg.ConvertToPDF() == 0)
{
Console.WriteLine("PDF created successfully");
}
}
}
// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;
class Program
{
static void Main()
{
WebGrabber wg = new WebGrabber();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
File.WriteAllText(tempHtml, htmlContent);
wg.URL = tempHtml;
wg.OutputDirectory = Directory.GetCurrentDirectory();
wg.OutputFilename = "output.pdf";
if (wg.ConvertToPDF() == 0)
{
Console.WriteLine("PDF created successfully");
}
}
}
Imports APWebGrabber
Imports System
Imports System.IO
Module Program
Sub Main()
Dim wg As New WebGrabber()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
Dim tempHtml As String = Path.Combine(Path.GetTempPath(), "input.html")
File.WriteAllText(tempHtml, htmlContent)
wg.URL = tempHtml
wg.OutputDirectory = Directory.GetCurrentDirectory()
wg.OutputFilename = "output.pdf"
If wg.ConvertToPDF() = 0 Then
Console.WriteLine("PDF created successfully")
End If
End Sub
End Module
IronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
Imports IronPdf
Imports System
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Module
The IronPDF approach eliminates the explicit file handle management while providing cleaner, more readable code. For advanced HTML to PDF scenarios, IronPDF's ChromePdfRenderer uses a Chromium-based rendering engine for pixel-perfect CSS and JavaScript support.
URL to PDF Conversion
Capturing web pages as PDF documents also lives in WebGrabber, not Toolkit.
ActivePDF Implementation (WebGrabber):
// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;
class Program
{
static void Main()
{
WebGrabber wg = new WebGrabber();
wg.URL = "https://www.example.com";
wg.OutputDirectory = Directory.GetCurrentDirectory();
wg.OutputFilename = "webpage.pdf";
if (wg.ConvertToPDF() == 0)
{
Console.WriteLine("PDF from URL created successfully");
}
}
}
// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;
class Program
{
static void Main()
{
WebGrabber wg = new WebGrabber();
wg.URL = "https://www.example.com";
wg.OutputDirectory = Directory.GetCurrentDirectory();
wg.OutputFilename = "webpage.pdf";
if (wg.ConvertToPDF() == 0)
{
Console.WriteLine("PDF from URL created successfully");
}
}
}
Imports APWebGrabber
Imports System
Imports System.IO
Module Program
Sub Main()
Dim wg As New WebGrabber()
wg.URL = "https://www.example.com"
wg.OutputDirectory = Directory.GetCurrentDirectory()
wg.OutputFilename = "webpage.pdf"
If wg.ConvertToPDF() = 0 Then
Console.WriteLine("PDF from URL created successfully")
End If
End Sub
End Module
IronPDF Implementation:
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string url = "https://www.example.com";
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string url = "https://www.example.com";
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim url As String = "https://www.example.com"
Dim pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF from URL created successfully")
End Sub
End Class
Merging Multiple PDFs
Combining multiple PDF documents into a single file demonstrates IronPDF's functional approach to document manipulation.
ActivePDF Implementation (Toolkit):
// NuGet: Install-Package ActivePDF.Toolkit
using APToolkitNET;
using System;
class Program
{
static void Main()
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile("merged.pdf") == 0)
{
// MergeFile(FileName, StartPage, EndPage); -1 = end of file
toolkit.MergeFile("document1.pdf", 1, -1);
toolkit.MergeFile("document2.pdf", 1, -1);
toolkit.CloseOutputFile();
Console.WriteLine("PDFs merged successfully");
}
}
}
}
// NuGet: Install-Package ActivePDF.Toolkit
using APToolkitNET;
using System;
class Program
{
static void Main()
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile("merged.pdf") == 0)
{
// MergeFile(FileName, StartPage, EndPage); -1 = end of file
toolkit.MergeFile("document1.pdf", 1, -1);
toolkit.MergeFile("document2.pdf", 1, -1);
toolkit.CloseOutputFile();
Console.WriteLine("PDFs merged successfully");
}
}
}
}
Imports APToolkitNET
Imports System
Module Program
Sub Main()
Using toolkit As New Toolkit()
If toolkit.OpenOutputFile("merged.pdf") = 0 Then
' MergeFile(FileName, StartPage, EndPage); -1 = end of file
toolkit.MergeFile("document1.pdf", 1, -1)
toolkit.MergeFile("document2.pdf", 1, -1)
toolkit.CloseOutputFile()
Console.WriteLine("PDFs merged successfully")
End If
End Using
End Sub
End Module
IronPDF Implementation:
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
Console.WriteLine("PDFs merged successfully")
End Sub
End Module
For more advanced merging scenarios including selective page extraction, see the PDF merging documentation.
Adding Headers and Footers
ActivePDF Implementation (WebGrabber):
using APWebGrabber;
using System.IO;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var wg = new WebGrabber();
string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
File.WriteAllText(tempHtml, html);
wg.URL = tempHtml;
wg.HeaderText = "My Document";
wg.FooterText = "Page [page] of [pages]";
wg.OutputDirectory = Path.GetDirectoryName(outputPath);
wg.OutputFilename = Path.GetFileName(outputPath);
wg.ConvertToPDF();
}
using APWebGrabber;
using System.IO;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var wg = new WebGrabber();
string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
File.WriteAllText(tempHtml, html);
wg.URL = tempHtml;
wg.HeaderText = "My Document";
wg.FooterText = "Page [page] of [pages]";
wg.OutputDirectory = Path.GetDirectoryName(outputPath);
wg.OutputFilename = Path.GetFileName(outputPath);
wg.ConvertToPDF();
}
Imports APWebGrabber
Imports System.IO
Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
Dim wg As New WebGrabber()
Dim tempHtml As String = Path.Combine(Path.GetTempPath(), "input.html")
File.WriteAllText(tempHtml, html)
wg.URL = tempHtml
wg.HeaderText = "My Document"
wg.FooterText = "Page [page] of [pages]"
wg.OutputDirectory = Path.GetDirectoryName(outputPath)
wg.OutputFilename = Path.GetFileName(outputPath)
wg.ConvertToPDF()
End Sub
IronPDF Implementation:
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "My Document",
FontSize = 12,
FontFamily = "Arial"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Arial"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "My Document",
FontSize = 12,
FontFamily = "Arial"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Arial"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "My Document",
.FontSize = 12,
.FontFamily = "Arial"
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page} of {total-pages}",
.FontSize = 10,
.FontFamily = "Arial"
}
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF supports both text-based and HTML headers and footers, providing complete design flexibility.
Password Protection and Security
ActivePDF Implementation (Toolkit):
using APToolkitNET;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile(outputPath) == 0
&& toolkit.OpenInputFile(inputPath) == 0)
{
toolkit.SetEncryption(password, password, 128, 0);
toolkit.CopyForm(0, 0);
toolkit.CloseInputFile();
toolkit.CloseOutputFile();
}
}
}
using APToolkitNET;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile(outputPath) == 0
&& toolkit.OpenInputFile(inputPath) == 0)
{
toolkit.SetEncryption(password, password, 128, 0);
toolkit.CopyForm(0, 0);
toolkit.CloseInputFile();
toolkit.CloseOutputFile();
}
}
}
Imports APToolkitNET
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Using toolkit As New Toolkit()
If toolkit.OpenOutputFile(outputPath) = 0 AndAlso toolkit.OpenInputFile(inputPath) = 0 Then
toolkit.SetEncryption(password, password, 128, 0)
toolkit.CopyForm(0, 0)
toolkit.CloseInputFile()
toolkit.CloseOutputFile()
End If
End Using
End Sub
IronPDF Implementation:
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.SecuritySettings.OwnerPassword = password
pdf.SecuritySettings.UserPassword = password
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF's security settings API provides granular control over document permissions with strongly-typed enums instead of integer flags.
Text Extraction
ActivePDF Implementation (Toolkit):
using APToolkitNET;
using System.Text;
public string ExtractText(string pdfPath)
{
var sb = new StringBuilder();
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenInputFile(pdfPath) == 0)
{
int pageCount = toolkit.NumPages;
for (int i = 1; i <= pageCount; i++)
{
sb.AppendLine(toolkit.GetPageText(i, 0));
}
toolkit.CloseInputFile();
}
}
return sb.ToString();
}
using APToolkitNET;
using System.Text;
public string ExtractText(string pdfPath)
{
var sb = new StringBuilder();
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenInputFile(pdfPath) == 0)
{
int pageCount = toolkit.NumPages;
for (int i = 1; i <= pageCount; i++)
{
sb.AppendLine(toolkit.GetPageText(i, 0));
}
toolkit.CloseInputFile();
}
}
return sb.ToString();
}
Imports APToolkitNET
Imports System.Text
Public Function ExtractText(pdfPath As String) As String
Dim sb As New StringBuilder()
Using toolkit As New Toolkit()
If toolkit.OpenInputFile(pdfPath) = 0 Then
Dim pageCount As Integer = toolkit.NumPages
For i As Integer = 1 To pageCount
sb.AppendLine(toolkit.GetPageText(i, 0))
Next
toolkit.CloseInputFile()
End If
End Using
Return sb.ToString()
End Function
IronPDF Implementation:
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
Imports IronPdf
Public Function ExtractText(pdfPath As String) As String
Using pdf = PdfDocument.FromFile(pdfPath)
Return pdf.ExtractAllText()
End Using
End Function
The IronPDF implementation reduces text extraction from multiple lines to a single method call.
Adding Watermarks
ActivePDF Implementation (Toolkit — drawn as page text per page):
using APToolkitNET;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile(outputPath) == 0
&& toolkit.OpenInputFile(inputPath) == 0)
{
int pageCount = toolkit.NumPages;
for (int i = 1; i <= pageCount; i++)
{
toolkit.CopyForm(i, 0);
toolkit.SetFont("Helvetica", 72);
toolkit.SetTextColor(200, 200, 200);
toolkit.PrintText(150, 400, watermarkText);
}
toolkit.CloseInputFile();
toolkit.CloseOutputFile();
}
}
}
using APToolkitNET;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using (Toolkit toolkit = new Toolkit())
{
if (toolkit.OpenOutputFile(outputPath) == 0
&& toolkit.OpenInputFile(inputPath) == 0)
{
int pageCount = toolkit.NumPages;
for (int i = 1; i <= pageCount; i++)
{
toolkit.CopyForm(i, 0);
toolkit.SetFont("Helvetica", 72);
toolkit.SetTextColor(200, 200, 200);
toolkit.PrintText(150, 400, watermarkText);
}
toolkit.CloseInputFile();
toolkit.CloseOutputFile();
}
}
}
Imports APToolkitNET
Public Sub AddWatermark(inputPath As String, outputPath As String, watermarkText As String)
Using toolkit As New Toolkit()
If toolkit.OpenOutputFile(outputPath) = 0 AndAlso toolkit.OpenInputFile(inputPath) = 0 Then
Dim pageCount As Integer = toolkit.NumPages
For i As Integer = 1 To pageCount
toolkit.CopyForm(i, 0)
toolkit.SetFont("Helvetica", 72)
toolkit.SetTextColor(200, 200, 200)
toolkit.PrintText(150, 400, watermarkText)
Next
toolkit.CloseInputFile()
toolkit.CloseOutputFile()
End If
End Using
End Sub
IronPDF Implementation:
using IronPdf;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation: 45,
opacity: 50);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation: 45,
opacity: 50);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub AddWatermark(inputPath As String, outputPath As String, watermarkText As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation:=45,
opacity:=50)
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF's HTML-based watermarking enables CSS styling for complete design control without page-by-page iteration.
ASP.NET Core Integration
Modern web applications benefit significantly from IronPDF's cleaner integration patterns.
ActivePDF Pattern (WebGrabber):
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var wg = new APWebGrabber.WebGrabber();
string tempHtml = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".html");
System.IO.File.WriteAllText(tempHtml, request.Html);
wg.URL = tempHtml;
wg.OutputDirectory = Path.GetTempPath();
wg.OutputFilename = "temp.pdf";
if (wg.ConvertToPDF() == 0)
{
byte[] bytes = System.IO.File.ReadAllBytes(Path.Combine(Path.GetTempPath(), "temp.pdf"));
return File(bytes, "application/pdf", "report.pdf");
}
return BadRequest("PDF generation failed");
}
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var wg = new APWebGrabber.WebGrabber();
string tempHtml = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".html");
System.IO.File.WriteAllText(tempHtml, request.Html);
wg.URL = tempHtml;
wg.OutputDirectory = Path.GetTempPath();
wg.OutputFilename = "temp.pdf";
if (wg.ConvertToPDF() == 0)
{
byte[] bytes = System.IO.File.ReadAllBytes(Path.Combine(Path.GetTempPath(), "temp.pdf"));
return File(bytes, "application/pdf", "report.pdf");
}
return BadRequest("PDF generation failed");
}
Imports System
Imports System.IO
Imports Microsoft.AspNetCore.Mvc
<HttpPost>
Public Function GeneratePdf(<FromBody> request As ReportRequest) As IActionResult
Dim wg As New APWebGrabber.WebGrabber()
Dim tempHtml As String = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() & ".html")
System.IO.File.WriteAllText(tempHtml, request.Html)
wg.URL = tempHtml
wg.OutputDirectory = Path.GetTempPath()
wg.OutputFilename = "temp.pdf"
If wg.ConvertToPDF() = 0 Then
Dim bytes As Byte() = System.IO.File.ReadAllBytes(Path.Combine(Path.GetTempPath(), "temp.pdf"))
Return File(bytes, "application/pdf", "report.pdf")
End If
Return BadRequest("PDF generation failed")
End Function
IronPDF Pattern:
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(request.Html);
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(request.Html);
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
<HttpPost>
Public Function GeneratePdf(<FromBody> request As ReportRequest) As IActionResult
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(request.Html)
Return File(pdf.BinaryData, "application/pdf", "report.pdf")
End Using
End Function
IronPDF eliminates the need for temporary files, returning the PDF binary data directly from memory.
Async Support for Web Applications
ActivePDF lacks native async support. IronPDF provides full async/await capabilities essential for scalable web applications:
using IronPdf;
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
using IronPdf;
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
Imports IronPdf
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
Dependency Injection Configuration
For .NET 6+ applications, register IronPDF services in your DI container:
// Program.cs (.NET 6+)
builder.Services.AddSingleton<ChromePdfRenderer>();
// Service wrapper
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
Task<byte[]> GeneratePdfFromUrlAsync(string url);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfFromUrlAsync(string url)
{
using var pdf = await _renderer.RenderUrlAsPdfAsync(url);
return pdf.BinaryData;
}
}
// Program.cs (.NET 6+)
builder.Services.AddSingleton<ChromePdfRenderer>();
// Service wrapper
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
Task<byte[]> GeneratePdfFromUrlAsync(string url);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfFromUrlAsync(string url)
{
using var pdf = await _renderer.RenderUrlAsPdfAsync(url);
return pdf.BinaryData;
}
}
Imports Microsoft.Extensions.DependencyInjection
Imports System.Threading.Tasks
' Program.vb (.NET 6+)
builder.Services.AddSingleton(Of ChromePdfRenderer)()
' Service wrapper
Public Interface IPdfService
Function GeneratePdfAsync(html As String) As Task(Of Byte())
Function GeneratePdfFromUrlAsync(url As String) As Task(Of Byte())
End Interface
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte()) Implements IPdfService.GeneratePdfAsync
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
Public Async Function GeneratePdfFromUrlAsync(url As String) As Task(Of Byte()) Implements IPdfService.GeneratePdfFromUrlAsync
Using pdf = Await _renderer.RenderUrlAsPdfAsync(url)
Return pdf.BinaryData
End Using
End Function
End Class
Error Handling Migration
ActivePDF uses integer return codes requiring lookup tables. IronPDF uses modern exception handling:
ActivePDF Error Handling:
using APToolkitNET;
using (var toolkit = new Toolkit())
{
int result = toolkit.OpenOutputFile(path);
if (result != 0)
{
// Error - look up the code in "Toolkit Return Results and Error Codes"
Console.WriteLine($"Error code: {result}");
}
}
using APToolkitNET;
using (var toolkit = new Toolkit())
{
int result = toolkit.OpenOutputFile(path);
if (result != 0)
{
// Error - look up the code in "Toolkit Return Results and Error Codes"
Console.WriteLine($"Error code: {result}");
}
}
Imports APToolkitNET
Using toolkit As New Toolkit()
Dim result As Integer = toolkit.OpenOutputFile(path)
If result <> 0 Then
' Error - look up the code in "Toolkit Return Results and Error Codes"
Console.WriteLine($"Error code: {result}")
End If
End Using
IronPDF Error Handling:
try
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path);
}
catch (IronPdf.Exceptions.IronPdfProductException ex)
{
Console.WriteLine($"IronPDF Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"General Error: {ex.Message}");
}
try
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path);
}
catch (IronPdf.Exceptions.IronPdfProductException ex)
{
Console.WriteLine($"IronPDF Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"General Error: {ex.Message}");
}
Imports IronPdf.Exceptions
Try
Dim renderer = New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(path)
End Using
Catch ex As IronPdfProductException
Console.WriteLine($"IronPDF Error: {ex.Message}")
Catch ex As Exception
Console.WriteLine($"General Error: {ex.Message}")
End Try
Performance Optimization Tips
Reuse the Renderer Instance
Creating a new ChromePdfRenderer has initialization overhead. For batch operations, reuse a single instance:
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
For Each html In htmlList
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"output_{i}.pdf")
End Using
Next
Use Async in Web Applications
For ASP.NET Core applications, async PDF generation improves throughput:
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Public Async Function GenerateReport() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Using
End Function
End Class
Proper Resource Disposal
Always use using statements to ensure proper cleanup:
using var pdf = renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
using var pdf = renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
Image Compression
Reduce output file sizes with image compression:
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.CompressImages(85); // 85% quality
pdf.SaveAs("compressed.pdf");
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.CompressImages(85); // 85% quality
pdf.SaveAs("compressed.pdf");
Troubleshooting Common Migration Issues
Issue: Page Size Differences
ActivePDF WebGrabber uses points (612x792 = Letter), while IronPDF uses enums or millimeters:
// ActivePDF WebGrabber: Points
wg.PageWidth = 612;
wg.PageHeight = 792;
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4);
// ActivePDF WebGrabber: Points
wg.PageWidth = 612;
wg.PageHeight = 792;
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4);
' ActivePDF WebGrabber: Points
wg.PageWidth = 612
wg.PageHeight = 792
' IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
' Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4)
Issue: Missing CloseOutputFile Equivalent
IronPDF uses a modern paradigm without explicit file handle management:
// ActivePDF Toolkit
toolkit.OpenOutputFile(path);
// ... operations ...
toolkit.CloseOutputFile(); // Required!
// IronPDF - no open/close needed
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path); // 'using' handles cleanup
// ActivePDF Toolkit
toolkit.OpenOutputFile(path);
// ... operations ...
toolkit.CloseOutputFile(); // Required!
// IronPDF - no open/close needed
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path); // 'using' handles cleanup
Imports ActivePDF
Imports IronPdf
' ActivePDF Toolkit
toolkit.OpenOutputFile(path)
' ... operations ...
toolkit.CloseOutputFile() ' Required!
' IronPDF - no open/close needed
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(path) ' 'Using' handles cleanup
End Using
Issue: PDF Renders Blank
If JavaScript-dependent content renders blank, configure render delays:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.RenderDelay(2000);
// Or wait for element:
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.RenderDelay(2000);
// Or wait for element:
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.WaitFor.RenderDelay(2000)
' Or wait for element:
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded")
Issue: CSS/Images Not Loading
Configure the base URL for relative path resolution:
renderer.RenderingOptions.BaseUrl = new Uri("https://yourdomain.com/assets/");
renderer.RenderingOptions.BaseUrl = new Uri("https://yourdomain.com/assets/");
renderer.RenderingOptions.BaseUrl = New Uri("https://yourdomain.com/assets/")
Post-Migration Checklist
After completing the code migration, verify the following:
- Run all existing unit and integration tests
- Compare PDF outputs visually against previous versions
- Test all PDF workflows in a staging environment
- Verify licensing works correctly (
IronPdf.License.IsLicensed) - Benchmark performance against previous implementation
- Remove old ActivePDF installation files and DLL references
- Update CI/CD pipeline dependencies
- Document IronPDF patterns for your development team
Additional Resources
Migrating from ActivePDF to IronPDF modernizes your PDF generation infrastructure with cleaner APIs, better .NET integration, and active long-term support. The investment in migration pays dividends through improved code maintainability, async capabilities, and confidence in your PDF library's continued development.

