How to Migrate from Aspose.PDF to IronPDF in C#
Why Migrate Away from Aspose.PDF?
While Aspose.PDF delivers enterprise-grade functionality, several factors drive development teams to seek modern alternatives for their PDF generation needs.
Cost Comparison
Aspose.PDF uses a traditional enterprise licensing model with annual renewals that accumulate significantly over time:
| Aspect | Aspose.PDF | IronPDF |
|---|---|---|
| Starting Price | $1,199/developer/year | $749 one-time (Lite) |
| License Model | Annual subscription + renewal | Perpetual license |
| OEM License | $5,997+ additional | Included in higher tiers |
| Support | Extra cost tiers | Included |
| Total 3-Year Cost | $3,597+ per developer | $749 one-time |
HTML Rendering Engine Comparison
Aspose.PDF uses the Flying Saucer CSS engine, which struggles with modern web standards. IronPDF leverages a full Chromium rendering engine:
| Feature | Aspose.PDF (Flying Saucer) | IronPDF (Chromium) |
|---|---|---|
| CSS3 Support | Limited (older CSS) | Full CSS3 |
| Flexbox/Grid | Not supported | Supported |
| JavaScript | Very limited | Supported |
| Web Fonts | Partial | Complete |
| Modern HTML5 | Limited | Complete |
| Rendering Quality | Variable | Pixel-perfect |
Documented Performance Issues
Users have reported significant performance differences between the two libraries:
| Metric | Aspose.PDF | IronPDF |
|---|---|---|
| HTML Rendering | Documented slowdowns (30x slower in some cases) | Optimized Chromium engine |
| Large Documents | Memory issues reported | Efficient streaming |
| Linux Performance | High CPU, memory leaks reported | Stable |
Aspose.PDF vs. IronPDF: Key Differences
| Aspect | Aspose.PDF | IronPDF |
|---|---|---|
| Pricing | $1,199/developer/year (subscription) | $749 one-time (Lite) |
| HTML Engine | Flying Saucer (limited CSS) | Chromium (full CSS3/JS) |
| Performance | Documented slowdowns | Optimized |
| License Model | Annual renewal + .lic file | Perpetual + code-based key |
| Linux Support | Issues reported (CPU, memory) | Stable |
| Page Indexing | 1-based (Pages[1]) | 0-based (Pages[0]) |
Pre-Migration Preparation
Prerequisites
Ensure your environment meets these requirements:
- .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ or VS Code with C# extension
- NuGet Package Manager access
- IronPDF license key (free trial available at ironpdf.com)
Audit Aspose.PDF Usage
Run these commands in your solution directory to identify all Aspose.PDF references:
# Find all Aspose.Pdf using statements
grep -r "using Aspose.Pdf" --include="*.cs" .
# Find HtmlLoadOptions usage
grep -r "HtmlLoadOptions\|HtmlFragment" --include="*.cs" .
# Find Facades usage
grep -r "PdfFileEditor\|PdfFileMend\|PdfFileStamp" --include="*.cs" .
# Find TextAbsorber usage
grep -r "TextAbsorber\|TextFragmentAbsorber" --include="*.cs" .# Find all Aspose.Pdf using statements
grep -r "using Aspose.Pdf" --include="*.cs" .
# Find HtmlLoadOptions usage
grep -r "HtmlLoadOptions\|HtmlFragment" --include="*.cs" .
# Find Facades usage
grep -r "PdfFileEditor\|PdfFileMend\|PdfFileStamp" --include="*.cs" .
# Find TextAbsorber usage
grep -r "TextAbsorber\|TextFragmentAbsorber" --include="*.cs" .Breaking Changes to Anticipate
| Aspose.PDF Pattern | Change Required |
|---|---|
new Document() + Pages.Add() | Use HTML rendering instead |
HtmlLoadOptions | ChromePdfRenderer.RenderHtmlAsPdf() |
TextFragment + manual positioning | CSS-based positioning |
PdfFileEditor.Concatenate() | PdfDocument.Merge() |
TextFragmentAbsorber | pdf.ExtractAllText() |
ImageStamp | HTML-based watermarks |
.lic file licensing | Code-based license key |
| 1-based page indexing | 0-based page indexing |
Step-by-Step Migration Process
Step 1: Update NuGet Packages
Remove Aspose.PDF and install IronPDF:
# Remove Aspose.PDF
dotnet remove package Aspose.PDF
# Install IronPDF
dotnet add package IronPdf# Remove Aspose.PDF
dotnet remove package Aspose.PDF
# Install IronPDF
dotnet add package IronPdfOr via Package Manager Console:
Uninstall-Package Aspose.PDF
Install-Package IronPdfStep 2: Update Namespace References
Replace Aspose.PDF namespaces with IronPDF:
// Remove these
using Aspose.Pdf;
using Aspose.Pdf.Text;
using Aspose.Pdf.Facades;
using Aspose.Pdf.Generator;
// Add these
using IronPdf;
using IronPdf.Rendering;
using IronPdf.Editing;// Remove these
using Aspose.Pdf;
using Aspose.Pdf.Text;
using Aspose.Pdf.Facades;
using Aspose.Pdf.Generator;
// Add these
using IronPdf;
using IronPdf.Rendering;
using IronPdf.Editing;' Remove these
' Imports Aspose.Pdf
' Imports Aspose.Pdf.Text
' Imports Aspose.Pdf.Facades
' Imports Aspose.Pdf.Generator
' Add these
Imports IronPdf
Imports IronPdf.Rendering
Imports IronPdf.EditingStep 3: Update License Configuration
Aspose.PDF uses .lic file licensing. IronPDF uses a simple code-based key.
Aspose.PDF Implementation:
var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");Imports Aspose.Pdf
Dim license As New License()
license.SetLicense("Aspose.Pdf.lic")IronPDF Implementation:
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"Complete API Migration Reference
Core Class Mapping
| Aspose.PDF Class | IronPDF Equivalent |
|---|---|
Document | PdfDocument |
HtmlLoadOptions | ChromePdfRenderer |
TextFragmentAbsorber | PdfDocument.ExtractAllText() |
PdfFileEditor | PdfDocument.Merge() |
TextStamp / ImageStamp | PdfDocument.ApplyWatermark() |
License | IronPdf.License |
Document Operations
| Aspose.PDF Method | IronPDF Method |
|---|---|
new Document() | new PdfDocument() |
new Document(path) | PdfDocument.FromFile(path) |
doc.Save(path) | pdf.SaveAs(path) |
doc.Pages.Count | pdf.PageCount |
doc.Pages.Delete(index) | pdf.RemovePage(index) |
HTML to PDF Conversion
| Aspose.PDF Method | IronPDF Method |
|---|---|
new HtmlLoadOptions() | new ChromePdfRenderer() |
new Document(stream, htmlOptions) | renderer.RenderHtmlAsPdf(html) |
new Document(path, htmlOptions) | renderer.RenderHtmlFileAsPdf(path) |
Code Migration Examples
HTML String to PDF
The most common Aspose.PDF operation demonstrates the fundamental difference in approach—Aspose.PDF requires wrapping HTML in a MemoryStream, while IronPDF accepts strings directly.
Aspose.PDF Implementation:
// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(htmlContent)))
{
var htmlLoadOptions = new HtmlLoadOptions();
var document = new Document(stream, htmlLoadOptions);
document.Save("output.pdf");
}
Console.WriteLine("PDF created from HTML string");
}
}// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(htmlContent)))
{
var htmlLoadOptions = new HtmlLoadOptions();
var document = new Document(stream, htmlLoadOptions);
document.Save("output.pdf");
}
Console.WriteLine("PDF created from HTML string");
}
}Imports Aspose.Pdf
Imports System
Imports System.IO
Imports System.Text
Module Program
Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>"
Using stream As New MemoryStream(Encoding.UTF8.GetBytes(htmlContent))
Dim htmlLoadOptions As New HtmlLoadOptions()
Dim document As New Document(stream, htmlLoadOptions)
document.Save("output.pdf")
End Using
Console.WriteLine("PDF created from HTML string")
End Sub
End ModuleIronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created from HTML string");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created from HTML string");
}
}Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML string.</p></body></html>"
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created from HTML string")
End Sub
End ClassIronPDF eliminates the MemoryStream wrapper entirely—a cleaner, more intuitive API.
HTML File to PDF
Aspose.PDF Implementation:
// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
class Program
{
static void Main()
{
var htmlLoadOptions = new HtmlLoadOptions();
var document = new Document("input.html", htmlLoadOptions);
document.Save("output.pdf");
Console.WriteLine("PDF created successfully");
}
}// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
class Program
{
static void Main()
{
var htmlLoadOptions = new HtmlLoadOptions();
var document = new Document("input.html", htmlLoadOptions);
document.Save("output.pdf");
Console.WriteLine("PDF created successfully");
}
}Imports Aspose.Pdf
Imports System
Class Program
Shared Sub Main()
Dim htmlLoadOptions As New HtmlLoadOptions()
Dim document As New Document("input.html", htmlLoadOptions)
document.Save("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End ClassIronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
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();
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End ClassMerging Multiple PDFs
Aspose.PDF requires iterating through pages manually. IronPDF provides a static Merge method.
Aspose.PDF Implementation:
// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
class Program
{
static void Main()
{
var document1 = new Document("file1.pdf");
var document2 = new Document("file2.pdf");
foreach (Page page in document2.Pages)
{
document1.Pages.Add(page);
}
document1.Save("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}// NuGet: Install-Package Aspose.PDF
using Aspose.Pdf;
using System;
class Program
{
static void Main()
{
var document1 = new Document("file1.pdf");
var document2 = new Document("file2.pdf");
foreach (Page page in document2.Pages)
{
document1.Pages.Add(page);
}
document1.Save("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}Imports Aspose.Pdf
Imports System
Class Program
Shared Sub Main()
Dim document1 As New Document("file1.pdf")
Dim document2 As New Document("file2.pdf")
For Each page As Page In document2.Pages
document1.Pages.Add(page)
Next
document1.Save("merged.pdf")
Console.WriteLine("PDFs merged successfully")
End Sub
End ClassIronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("file1.pdf");
var pdf2 = PdfDocument.FromFile("file2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("file1.pdf");
var pdf2 = PdfDocument.FromFile("file2.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("file1.pdf")
Dim pdf2 = PdfDocument.FromFile("file2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
Console.WriteLine("PDFs merged successfully")
End Sub
End ModuleText Extraction
Aspose.PDF Implementation:
using Aspose.Pdf;
using Aspose.Pdf.Text;
var document = new Document("document.pdf");
var absorber = new TextAbsorber();
foreach (Page page in document.Pages)
{
page.Accept(absorber);
}
string extractedText = absorber.Text;
Console.WriteLine(extractedText);using Aspose.Pdf;
using Aspose.Pdf.Text;
var document = new Document("document.pdf");
var absorber = new TextAbsorber();
foreach (Page page in document.Pages)
{
page.Accept(absorber);
}
string extractedText = absorber.Text;
Console.WriteLine(extractedText);Imports Aspose.Pdf
Imports Aspose.Pdf.Text
Dim document As New Document("document.pdf")
Dim absorber As New TextAbsorber()
For Each page As Page In document.Pages
page.Accept(absorber)
Next
Dim extractedText As String = absorber.Text
Console.WriteLine(extractedText)IronPDF Implementation:
using IronPdf;
var pdf = PdfDocument.FromFile("document.pdf");
// Extract all text - one line!
string allText = pdf.ExtractAllText();
Console.WriteLine(allText);
// Or extract from specific page
string page1Text = pdf.ExtractTextFromPage(0);using IronPdf;
var pdf = PdfDocument.FromFile("document.pdf");
// Extract all text - one line!
string allText = pdf.ExtractAllText();
Console.WriteLine(allText);
// Or extract from specific page
string page1Text = pdf.ExtractTextFromPage(0);Imports IronPdf
Dim pdf = PdfDocument.FromFile("document.pdf")
' Extract all text - one line!
Dim allText As String = pdf.ExtractAllText()
Console.WriteLine(allText)
' Or extract from specific page
Dim page1Text As String = pdf.ExtractTextFromPage(0)IronPDF simplifies text extraction from multiple steps to a single method call.
Adding Watermarks
Aspose.PDF Implementation:
using Aspose.Pdf;
using Aspose.Pdf.Text;
var document = new Document("document.pdf");
var textStamp = new TextStamp("CONFIDENTIAL");
textStamp.Background = true;
textStamp.XIndent = 100;
textStamp.YIndent = 100;
textStamp.Rotate = Rotation.on45;
textStamp.Opacity = 0.5;
textStamp.TextState.Font = FontRepository.FindFont("Arial");
textStamp.TextState.FontSize = 72;
textStamp.TextState.ForegroundColor = Color.Red;
foreach (Page page in document.Pages)
{
page.AddStamp(textStamp);
}
document.Save("watermarked.pdf");using Aspose.Pdf;
using Aspose.Pdf.Text;
var document = new Document("document.pdf");
var textStamp = new TextStamp("CONFIDENTIAL");
textStamp.Background = true;
textStamp.XIndent = 100;
textStamp.YIndent = 100;
textStamp.Rotate = Rotation.on45;
textStamp.Opacity = 0.5;
textStamp.TextState.Font = FontRepository.FindFont("Arial");
textStamp.TextState.FontSize = 72;
textStamp.TextState.ForegroundColor = Color.Red;
foreach (Page page in document.Pages)
{
page.AddStamp(textStamp);
}
document.Save("watermarked.pdf");Imports Aspose.Pdf
Imports Aspose.Pdf.Text
Dim document As New Document("document.pdf")
Dim textStamp As New TextStamp("CONFIDENTIAL")
textStamp.Background = True
textStamp.XIndent = 100
textStamp.YIndent = 100
textStamp.Rotate = Rotation.on45
textStamp.Opacity = 0.5
textStamp.TextState.Font = FontRepository.FindFont("Arial")
textStamp.TextState.FontSize = 72
textStamp.TextState.ForegroundColor = Color.Red
For Each page As Page In document.Pages
page.AddStamp(textStamp)
Next
document.Save("watermarked.pdf")IronPDF Implementation:
using IronPdf;
using IronPdf.Editing;
var pdf = PdfDocument.FromFile("document.pdf");
// HTML-based watermark with full styling control
string watermarkHtml = @"
<div style='
color: red;
opacity: 0.5;
font-family: Arial;
font-size: 72px;
font-weight: bold;
text-align: center;
'>CONFIDENTIAL</div>";
pdf.ApplyWatermark(watermarkHtml,
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");using IronPdf;
using IronPdf.Editing;
var pdf = PdfDocument.FromFile("document.pdf");
// HTML-based watermark with full styling control
string watermarkHtml = @"
<div style='
color: red;
opacity: 0.5;
font-family: Arial;
font-size: 72px;
font-weight: bold;
text-align: center;
'>CONFIDENTIAL</div>";
pdf.ApplyWatermark(watermarkHtml,
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");Imports IronPdf
Imports IronPdf.Editing
Dim pdf = PdfDocument.FromFile("document.pdf")
' HTML-based watermark with full styling control
Dim watermarkHtml As String = "
<div style='
color: red;
opacity: 0.5;
font-family: Arial;
font-size: 72px;
font-weight: bold;
text-align: center;
'>CONFIDENTIAL</div>"
pdf.ApplyWatermark(watermarkHtml,
rotation:=45,
verticalAlignment:=VerticalAlignment.Middle,
horizontalAlignment:=HorizontalAlignment.Center)
pdf.SaveAs("watermarked.pdf")IronPDF uses HTML/CSS-based watermarking, providing full styling control through familiar web technologies.
Password Protection
Aspose.PDF Implementation:
using Aspose.Pdf;
var document = new Document("document.pdf");
document.Encrypt("userPassword", "ownerPassword", DocumentPrivilege.ForbidAll, CryptoAlgorithm.AESx256);
document.Save("protected.pdf");using Aspose.Pdf;
var document = new Document("document.pdf");
document.Encrypt("userPassword", "ownerPassword", DocumentPrivilege.ForbidAll, CryptoAlgorithm.AESx256);
document.Save("protected.pdf");Imports Aspose.Pdf
Dim document As New Document("document.pdf")
document.Encrypt("userPassword", "ownerPassword", DocumentPrivilege.ForbidAll, CryptoAlgorithm.AESx256)
document.Save("protected.pdf")IronPDF Implementation:
using IronPdf;
var pdf = PdfDocument.FromFile("document.pdf");
// Set passwords
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
// Set permissions
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");using IronPdf;
var pdf = PdfDocument.FromFile("document.pdf");
// Set passwords
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
// Set permissions
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");Imports IronPdf
Dim pdf = PdfDocument.FromFile("document.pdf")
' Set passwords
pdf.SecuritySettings.UserPassword = "userPassword"
pdf.SecuritySettings.OwnerPassword = "ownerPassword"
' Set permissions
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs("protected.pdf")IronPDF provides granular control over permissions through strongly-typed properties. For more options, see the encryption documentation.
Headers and Footers
IronPDF Implementation:
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align:center; font-family:Arial; font-size:12px;'>
Company Header
</div>",
DrawDividerLine = true,
MaxHeight = 30
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align:center; font-family:Arial; font-size:10px;'>
Page {page} of {total-pages}
</div>",
DrawDividerLine = true,
MaxHeight = 25
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Content here</h1>");
pdf.SaveAs("with_headers.pdf");using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align:center; font-family:Arial; font-size:12px;'>
Company Header
</div>",
DrawDividerLine = true,
MaxHeight = 30
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align:center; font-family:Arial; font-size:10px;'>
Page {page} of {total-pages}
</div>",
DrawDividerLine = true,
MaxHeight = 25
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Content here</h1>");
pdf.SaveAs("with_headers.pdf");Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "
<div style='text-align:center; font-family:Arial; font-size:12px;'>
Company Header
</div>",
.DrawDividerLine = True,
.MaxHeight = 30
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "
<div style='text-align:center; font-family:Arial; font-size:10px;'>
Page {page} of {total-pages}
</div>",
.DrawDividerLine = True,
.MaxHeight = 25
}
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Content here</h1>")
pdf.SaveAs("with_headers.pdf")IronPDF supports placeholder tokens like {page} and {total-pages} for dynamic page numbering. For more options, see the headers and footers documentation.
Critical Migration Notes
Page Indexing Change
Aspose.PDF uses 1-based indexing. IronPDF uses 0-based indexing:
// Aspose.PDF - 1-based indexing
var firstPage = doc.Pages[1]; // First page
var thirdPage = doc.Pages[3]; // Third page
// IronPDF - 0-based indexing
var firstPage = pdf.Pages[0]; // First page
var thirdPage = pdf.Pages[2]; // Third page// Aspose.PDF - 1-based indexing
var firstPage = doc.Pages[1]; // First page
var thirdPage = doc.Pages[3]; // Third page
// IronPDF - 0-based indexing
var firstPage = pdf.Pages[0]; // First page
var thirdPage = pdf.Pages[2]; // Third pageLicense File to Code Key
Replace .lic file licensing with code-based activation:
// Aspose.PDF
var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");
// IronPDF
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Or from environment variable
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY");// Aspose.PDF
var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");
// IronPDF
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Or from environment variable
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY");Imports Aspose.Pdf
Imports System
Dim license As New License()
license.SetLicense("Aspose.Pdf.lic")
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Or from environment variable
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")ASP.NET Core Integration
IronPDF Pattern:
[ApiController]
[Route("[controller]")]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}[ApiController]
[Route("[controller]")]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("[controller]")>
Public Class PdfController
Inherits ControllerBase
<HttpGet("generate")>
Public Function GeneratePdf() As IActionResult
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>")
Return File(pdf.BinaryData, "application/pdf", "report.pdf")
End Function
<HttpGet("generate-async")>
Public Async Function GeneratePdfAsync() As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>")
Return File(pdf.Stream, "application/pdf", "report.pdf")
End Function
End ClassDependency Injection Configuration
// Program.cs
public void ConfigureServices(IServiceCollection services)
{
// Set license once
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
// Register renderer as scoped service
services.AddScoped<ChromePdfRenderer>();
}// Program.cs
public void ConfigureServices(IServiceCollection services)
{
// Set license once
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
// Register renderer as scoped service
services.AddScoped<ChromePdfRenderer>();
}' Program.vb
Public Sub ConfigureServices(services As IServiceCollection)
' Set license once
IronPdf.License.LicenseKey = Configuration("IronPdf:LicenseKey")
' Register renderer as scoped service
services.AddScoped(Of ChromePdfRenderer)()
End SubPerformance Optimization
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
// 2. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
renderer.RenderingOptions.Timeout = 30000; // 30s max
// 3. Proper disposal
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
}// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
// 2. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
renderer.RenderingOptions.Timeout = 30000; // 30s max
// 3. Proper disposal
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
}' 1. Reuse renderer instance
Private Shared ReadOnly SharedRenderer As New ChromePdfRenderer()
' 2. Disable unnecessary features for speed
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = False ' If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0) ' No delay
renderer.RenderingOptions.Timeout = 30000 ' 30s max
' 3. Proper disposal
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End UsingTroubleshooting Common Migration Issues
Issue: HtmlLoadOptions Not Found
Replace with ChromePdfRenderer:
// Remove this
var doc = new Document(stream, new HtmlLoadOptions());
// Use this
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlString);// Remove this
var doc = new Document(stream, new HtmlLoadOptions());
// Use this
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlString);Dim doc = New Document(stream, New HtmlLoadOptions())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlString)Issue: TextFragmentAbsorber Not Found
Use direct text extraction:
// Remove this
var absorber = new TextFragmentAbsorber();
page.Accept(absorber);
string text = absorber.Text;
// Use this
var pdf = PdfDocument.FromFile("doc.pdf");
string text = pdf.ExtractAllText();// Remove this
var absorber = new TextFragmentAbsorber();
page.Accept(absorber);
string text = absorber.Text;
// Use this
var pdf = PdfDocument.FromFile("doc.pdf");
string text = pdf.ExtractAllText();' Remove this
Dim absorber As New TextFragmentAbsorber()
page.Accept(absorber)
Dim text As String = absorber.Text
' Use this
Dim pdf = PdfDocument.FromFile("doc.pdf")
Dim text As String = pdf.ExtractAllText()Issue: PdfFileEditor.Concatenate Not Available
Use PdfDocument.Merge():
// Remove this
var editor = new PdfFileEditor();
editor.Concatenate(files, output);
// Use this
var pdfs = files.Select(PdfDocument.FromFile).ToList();
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs(output);// Remove this
var editor = new PdfFileEditor();
editor.Concatenate(files, output);
// Use this
var pdfs = files.Select(PdfDocument.FromFile).ToList();
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs(output);' Remove this
Dim editor = New PdfFileEditor()
editor.Concatenate(files, output)
' Use this
Dim pdfs = files.Select(Function(file) PdfDocument.FromFile(file)).ToList()
Dim merged = PdfDocument.Merge(pdfs)
merged.SaveAs(output)Post-Migration Checklist
After completing the code migration, verify the following:
- Remove Aspose.PDF license files (.lic)
- Verify HTML rendering quality (CSS Grid, Flexbox should now work correctly)
- Test edge cases with large documents and complex CSS
- Update page index references (1-based to 0-based)
- Update Docker configurations if applicable
- Update CI/CD pipelines with new license key configuration
- Document new patterns for your team
Future-Proofing Your PDF Infrastructure
With .NET 10 on the horizon and C# 14 introducing new language features, choosing a PDF library with modern rendering capabilities ensures compatibility with evolving web standards. IronPDF's Chromium engine renders the same HTML/CSS that works in modern browsers, meaning your PDF templates stay current as projects extend into 2025 and 2026—without the CSS limitations of Aspose.PDF's Flying Saucer engine.
Additional Resources
Migrating from Aspose.PDF to IronPDF transforms your PDF codebase from an outdated HTML rendering engine to modern Chromium-based rendering. The elimination of MemoryStream wrappers, simplified text extraction, and superior CSS3 support deliver immediate productivity gains while reducing long-term licensing costs from annual subscriptions to a one-time investment.






