Skip to footer content
MIGRATION GUIDES

Migrate from ActivePDF to IronPDF: (.NET Guide)

ActivePDF has been a dependable PDF toolkit for .NET developers. However, since Foxit acquired it, many development teams are uncertain about the platform's future, licensing terms, and ongoing development. 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 and beyond.

Why Consider Moving Away from ActivePDF?

The acquisition of ActivePDF by Foxit has introduced several challenges for developers working on PDF generation and manipulation solutions in .NET applications.

Uncertain Product Future

ActivePDF's transition under Foxit's ownership raises questions about the toolkit's long-term development path. Developers relying on ActivePDF face potential risks of the library becoming outdated with reduced support and stagnant development. For teams planning projects extending into 2025 and 2026, this uncertainty creates significant technical risk.

Licensing Complications

The acquisition has introduced licensing uncertainties that can complicate deployments. ActivePDF's traditional machine-locked licensing model creates friction in modern cloud and containerized environments where applications scale dynamically across infrastructure.

Legacy Architecture Patterns

ActivePDF's architecture reflects an older design philosophy centered on stateful toolkit patterns. The OpenOutputFile/CloseOutputFile workflow requires explicit file handle management that doesn't align with modern C# conventions and can introduce resource management issues if not handled carefully.

Installation and Configuration Overhead

Unlike contemporary NuGet-based package management, ActivePDF often requires manual DLL references and explicit path configuration when instantiating the toolkit—a pattern that increases onboarding friction and complicates CI/CD pipelines.

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.

AspectActivePDFIronPDF
Company StatusAcquired by Foxit (uncertain future)Independent, clear development roadmap
InstallationManual DLL referencesSimple NuGet package
API PatternStateful (OpenOutputFile/CloseOutputFile)Fluent, functional API
License ModelMachine-lockedCode-based key
.NET SupportLegacy .NET Framework focusFramework 4.6.2 to .NET 9+
Error HandlingInteger return codesModern exception-based
Async SupportNot availableFull async/await support

Pre-Migration Preparation

Audit Your Codebase

Before beginning migration, identify all ActivePDF usage across your solution. Run these commands in your solution directory:

grep -r "using ActivePDF" --include="*.cs" .
grep -r "using APToolkitNET" --include="*.cs" .
grep -r "APToolkitNET" --include="*.csproj" .
grep -r "using ActivePDF" --include="*.cs" .
grep -r "using APToolkitNET" --include="*.cs" .
grep -r "APToolkitNET" --include="*.csproj" .
SHELL

Document Breaking Changes

Understanding the fundamental API differences helps plan your migration strategy:

CategoryActivePDF BehaviorIronPDF BehaviorMigration Action
Object ModelSingle Toolkit objectChromePdfRenderer + PdfDocumentSeparate concerns
File OperationsOpenOutputFile()/CloseOutputFile()Direct SaveAs()Remove open/close calls
Page CreationNewPage() methodAutomatic from HTMLRemove page creation calls
Return ValuesInteger error codesExceptionsImplement try/catch
Page Size UnitsPoints (612x792 = Letter)Enums or millimetersUpdate 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

Remove the ActivePDF package and install IronPDF:

# Remove ActivePDF package
dotnet remove package APToolkitNET

# Install IronPDF
dotnet add package IronPdf
# Remove ActivePDF package
dotnet remove package APToolkitNET

# Install IronPDF
dotnet add package IronPdf
SHELL

Alternatively, via the Visual Studio Package Manager Console:

Uninstall-Package APToolkitNET
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>
XML

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
$vbLabelText   $csharpLabel

Step 3: Update Namespace References

Perform a global find-and-replace across your solution:

FindReplace With
using ActivePDF.Toolkit;using IronPdf;
using APToolkitNET;using IronPdf;
using APToolkitNET.PDFObjects;using IronPdf;
using APToolkitNET.Common;using IronPdf;

Complete API Migration Reference

Document Creation Methods

ActivePDF MethodIronPDF Equivalent
new Toolkit()new ChromePdfRenderer()
toolkit.OpenOutputFile(path)No equivalent needed
toolkit.CloseOutputFile()No equivalent needed
toolkit.AddHTML(html)renderer.RenderHtmlAsPdf(html)
toolkit.AddURL(url)renderer.RenderUrlAsPdf(url)
toolkit.SaveAs(path)pdf.SaveAs(path)

File Operations

ActivePDF MethodIronPDF Equivalent
toolkit.OpenInputFile(path)PdfDocument.FromFile(path)
toolkit.AddPDF(path)PdfDocument.Merge()
toolkit.GetPageCount()pdf.PageCount
toolkit.GetText()pdf.ExtractAllText()

Page Configuration

ActivePDF MethodIronPDF 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 MethodIronPDF Equivalent
toolkit.Encrypt(password)pdf.SecuritySettings.OwnerPassword
toolkit.SetUserPassword(pwd)pdf.SecuritySettings.UserPassword
toolkit.SetPermissions(flags)pdf.SecuritySettings.AllowUserXxx
toolkit.AddWatermark(text)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. Here's how the code transforms during migration.

ActivePDF Implementation:

// NuGet: Install-Package APToolkitNET
using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        string htmlContent = "<html><body><h1>Hello World</h1></body></html>";

        if (toolkit.OpenOutputFile("output.pdf") == 0)
        {
            toolkit.AddHTML(htmlContent);
            toolkit.CloseOutputFile();
            Console.WriteLine("PDF created successfully");
        }
    }
}
// NuGet: Install-Package APToolkitNET
using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        string htmlContent = "<html><body><h1>Hello World</h1></body></html>";

        if (toolkit.OpenOutputFile("output.pdf") == 0)
        {
            toolkit.AddHTML(htmlContent);
            toolkit.CloseOutputFile();
            Console.WriteLine("PDF created successfully");
        }
    }
}
Imports ActivePDF.Toolkit
Imports System

Class Program
    Shared Sub Main()
        Dim toolkit As New Toolkit()

        Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"

        If toolkit.OpenOutputFile("output.pdf") = 0 Then
            toolkit.AddHTML(htmlContent)
            toolkit.CloseOutputFile()
            Console.WriteLine("PDF created successfully")
        End If
    End Sub
End Class
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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 follows a similar modernization pattern.

ActivePDF Implementation:

using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        string url = "https://www.example.com";

        if (toolkit.OpenOutputFile("webpage.pdf") == 0)
        {
            toolkit.AddURL(url);
            toolkit.CloseOutputFile();
            Console.WriteLine("PDF from URL created successfully");
        }
    }
}
using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        string url = "https://www.example.com";

        if (toolkit.OpenOutputFile("webpage.pdf") == 0)
        {
            toolkit.AddURL(url);
            toolkit.CloseOutputFile();
            Console.WriteLine("PDF from URL created successfully");
        }
    }
}
Imports ActivePDF.Toolkit
Imports System

Class Program
    Shared Sub Main()
        Dim toolkit As New Toolkit()

        Dim url As String = "https://www.example.com"

        If toolkit.OpenOutputFile("webpage.pdf") = 0 Then
            toolkit.AddURL(url)
            toolkit.CloseOutputFile()
            Console.WriteLine("PDF from URL created successfully")
        End If
    End Sub
End Class
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Merging Multiple PDFs

Combining multiple PDF documents into a single file demonstrates IronPDF's functional approach to document manipulation.

ActivePDF Implementation:

using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        if (toolkit.OpenOutputFile("merged.pdf") == 0)
        {
            toolkit.AddPDF("document1.pdf");
            toolkit.AddPDF("document2.pdf");
            toolkit.CloseOutputFile();
            Console.WriteLine("PDFs merged successfully");
        }
    }
}
using ActivePDF.Toolkit;
using System;

class Program
{
    static void Main()
    {
        Toolkit toolkit = new Toolkit();

        if (toolkit.OpenOutputFile("merged.pdf") == 0)
        {
            toolkit.AddPDF("document1.pdf");
            toolkit.AddPDF("document2.pdf");
            toolkit.CloseOutputFile();
            Console.WriteLine("PDFs merged successfully");
        }
    }
}
Imports ActivePDF.Toolkit
Imports System

Class Program
    Shared Sub Main()
        Dim toolkit As New Toolkit()

        If toolkit.OpenOutputFile("merged.pdf") = 0 Then
            toolkit.AddPDF("document1.pdf")
            toolkit.AddPDF("document2.pdf")
            toolkit.CloseOutputFile()
            Console.WriteLine("PDFs merged successfully")
        End If
    End Sub
End Class
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

For more advanced merging scenarios including selective page extraction, see the PDF merging documentation.

Adding Headers and Footers

ActivePDF Implementation:

using ActivePDF.Toolkit;

public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenOutputFile(outputPath) == 0)
    {
        toolkit.SetHeader("My Document", 12, "Arial");
        toolkit.SetFooter("Page %p of %P", 10, "Arial");
        toolkit.AddHTML(html);
        toolkit.CloseOutputFile();
    }
}
using ActivePDF.Toolkit;

public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenOutputFile(outputPath) == 0)
    {
        toolkit.SetHeader("My Document", 12, "Arial");
        toolkit.SetFooter("Page %p of %P", 10, "Arial");
        toolkit.AddHTML(html);
        toolkit.CloseOutputFile();
    }
}
Imports ActivePDF.Toolkit

Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
    Dim toolkit As New Toolkit()

    If toolkit.OpenOutputFile(outputPath) = 0 Then
        toolkit.SetHeader("My Document", 12, "Arial")
        toolkit.SetFooter("Page %p of %P", 10, "Arial")
        toolkit.AddHTML(html)
        toolkit.CloseOutputFile()
    End If
End Sub
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF supports both text-based and HTML headers and footers, providing complete design flexibility.

Password Protection and Security

ActivePDF Implementation:

using ActivePDF.Toolkit;

public void ProtectPdf(string inputPath, string outputPath, string password)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenInputFile(inputPath) == 0)
    {
        toolkit.Encrypt(password);
        toolkit.SetUserPassword(password);
        toolkit.SetPermissions(4); // Print only
        toolkit.SaveAs(outputPath);
        toolkit.CloseInputFile();
    }
}
using ActivePDF.Toolkit;

public void ProtectPdf(string inputPath, string outputPath, string password)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenInputFile(inputPath) == 0)
    {
        toolkit.Encrypt(password);
        toolkit.SetUserPassword(password);
        toolkit.SetPermissions(4); // Print only
        toolkit.SaveAs(outputPath);
        toolkit.CloseInputFile();
    }
}
Imports ActivePDF.Toolkit

Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
    Dim toolkit As New Toolkit()

    If toolkit.OpenInputFile(inputPath) = 0 Then
        toolkit.Encrypt(password)
        toolkit.SetUserPassword(password)
        toolkit.SetPermissions(4) ' Print only
        toolkit.SaveAs(outputPath)
        toolkit.CloseInputFile()
    End If
End Sub
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF's security settings API provides granular control over document permissions with strongly-typed enums instead of integer flags.

Text Extraction

ActivePDF Implementation:

using ActivePDF.Toolkit;

public string ExtractText(string pdfPath)
{
    Toolkit toolkit = new Toolkit();
    string text = "";

    if (toolkit.OpenInputFile(pdfPath) == 0)
    {
        int pageCount = toolkit.GetPageCount();
        for (int i = 1; i <= pageCount; i++)
        {
            text += toolkit.GetTextFromPage(i) + "\n";
        }
        toolkit.CloseInputFile();
    }

    return text;
}
using ActivePDF.Toolkit;

public string ExtractText(string pdfPath)
{
    Toolkit toolkit = new Toolkit();
    string text = "";

    if (toolkit.OpenInputFile(pdfPath) == 0)
    {
        int pageCount = toolkit.GetPageCount();
        for (int i = 1; i <= pageCount; i++)
        {
            text += toolkit.GetTextFromPage(i) + "\n";
        }
        toolkit.CloseInputFile();
    }

    return text;
}
Imports ActivePDF.Toolkit

Public Function ExtractText(pdfPath As String) As String
    Dim toolkit As New Toolkit()
    Dim text As String = ""

    If toolkit.OpenInputFile(pdfPath) = 0 Then
        Dim pageCount As Integer = toolkit.GetPageCount()
        For i As Integer = 1 To pageCount
            text &= toolkit.GetTextFromPage(i) & vbCrLf
        Next
        toolkit.CloseInputFile()
    End If

    Return text
End Function
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

The IronPDF implementation reduces text extraction from multiple lines to a single method call.

Adding Watermarks

ActivePDF Implementation:

using ActivePDF.Toolkit;

public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenInputFile(inputPath) == 0)
    {
        int pageCount = toolkit.GetPageCount();
        for (int i = 1; i <= pageCount; i++)
        {
            toolkit.SetPage(i);
            toolkit.AddWatermark(watermarkText, 45, 0.5f);
        }
        toolkit.SaveAs(outputPath);
        toolkit.CloseInputFile();
    }
}
using ActivePDF.Toolkit;

public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenInputFile(inputPath) == 0)
    {
        int pageCount = toolkit.GetPageCount();
        for (int i = 1; i <= pageCount; i++)
        {
            toolkit.SetPage(i);
            toolkit.AddWatermark(watermarkText, 45, 0.5f);
        }
        toolkit.SaveAs(outputPath);
        toolkit.CloseInputFile();
    }
}
Imports ActivePDF.Toolkit

Public Sub AddWatermark(inputPath As String, outputPath As String, watermarkText As String)
    Dim toolkit As New Toolkit()

    If toolkit.OpenInputFile(inputPath) = 0 Then
        Dim pageCount As Integer = toolkit.GetPageCount()
        For i As Integer = 1 To pageCount
            toolkit.SetPage(i)
            toolkit.AddWatermark(watermarkText, 45, 0.5F)
        Next
        toolkit.SaveAs(outputPath)
        toolkit.CloseInputFile()
    End If
End Sub
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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:

[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenOutputFile("temp.pdf") == 0)
    {
        toolkit.AddHTML(request.Html);
        toolkit.CloseOutputFile();

        byte[] bytes = System.IO.File.ReadAllBytes("temp.pdf");
        return File(bytes, "application/pdf", "report.pdf");
    }

    return BadRequest("PDF generation failed");
}
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
    Toolkit toolkit = new Toolkit();

    if (toolkit.OpenOutputFile("temp.pdf") == 0)
    {
        toolkit.AddHTML(request.Html);
        toolkit.CloseOutputFile();

        byte[] bytes = System.IO.File.ReadAllBytes("temp.pdf");
        return File(bytes, "application/pdf", "report.pdf");
    }

    return BadRequest("PDF generation failed");
}
<HttpPost>
Public Function GeneratePdf(<FromBody> request As ReportRequest) As IActionResult
    Dim toolkit As New Toolkit()

    If toolkit.OpenOutputFile("temp.pdf") = 0 Then
        toolkit.AddHTML(request.Html)
        toolkit.CloseOutputFile()

        Dim bytes As Byte() = System.IO.File.ReadAllBytes("temp.pdf")
        Return File(bytes, "application/pdf", "report.pdf")
    End If

    Return BadRequest("PDF generation failed")
End Function
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Error Handling Migration

ActivePDF uses integer return codes requiring lookup tables. IronPDF uses modern exception handling:

ActivePDF Error Handling:

Toolkit toolkit = new Toolkit();
int result = toolkit.OpenOutputFile(path);

if (result != 0)
{
    // Error - need to look up error code
    Console.WriteLine($"Error code: {result}");
}
Toolkit toolkit = new Toolkit();
int result = toolkit.OpenOutputFile(path);

if (result != 0)
{
    // Error - need to look up error code
    Console.WriteLine($"Error code: {result}");
}
Dim toolkit As New Toolkit()
Dim result As Integer = toolkit.OpenOutputFile(path)

If result <> 0 Then
    ' Error - need to look up error code
    Console.WriteLine($"Error code: {result}")
End If
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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;
net
$vbLabelText   $csharpLabel

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");
net
$vbLabelText   $csharpLabel

Troubleshooting Common Migration Issues

Issue: Page Size Differences

ActivePDF uses points (612x792 = Letter), while IronPDF uses enums or millimeters:

// ActivePDF: Points
toolkit.SetPageSize(612, 792);

// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4);
// ActivePDF: Points
toolkit.SetPageSize(612, 792);

// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4);
' ActivePDF: Points
toolkit.SetPageSize(612, 792)

' IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
' Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4)
$vbLabelText   $csharpLabel

Issue: Missing CloseOutputFile Equivalent

IronPDF uses a modern paradigm without explicit file handle management:

// ActivePDF
toolkit.OpenOutputFile(path);
toolkit.AddHTML(html);
toolkit.CloseOutputFile(); // Required!

// IronPDF - no open/close needed
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path); // 'using' handles cleanup
// ActivePDF
toolkit.OpenOutputFile(path);
toolkit.AddHTML(html);
toolkit.CloseOutputFile(); // Required!

// IronPDF - no open/close needed
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path); // 'using' handles cleanup
' ActivePDF
toolkit.OpenOutputFile(path)
toolkit.AddHTML(html)
toolkit.CloseOutputFile() ' Required!

' IronPDF - no open/close needed
Using pdf = renderer.RenderHtmlAsPdf(html)
    pdf.SaveAs(path) ' 'Using' handles cleanup
End Using
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

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/")
$vbLabelText   $csharpLabel

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

Future-Proofing Your PDF Solution

With .NET 10 on the horizon and C# 14 introducing new language features, choosing a .NET PDF library with active development ensures your applications remain compatible with evolving runtime capabilities. IronPDF's commitment to supporting the latest .NET versions means your migration investment pays dividends as your projects extend into 2025 and 2026.

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.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More