Skip to footer content
MIGRATION GUIDES

Migrating from Haukcode.DinkToPdf to IronPDF

Haukcode.DinkToPdf is a continuation of the once-popular DinkToPdf library, which uses the wkhtmltopdf binary to convert HTML to PDF for .NET applications. Although Haukcode.DinkToPdf kept up with .NET Core after the original project stalled, it carries significant security issues from its upstream dependency. The wkhtmltopdf project was archived in January 2023, so these issues will never be resolved.

This guide offers a thorough migration path from Haukcode.DinkToPdf to IronPDF, including step-by-step instructions, code comparisons, and practical examples for professional .NET developers aiming to remove security risks from their PDF generation workflows.

Critical Security Warning: CVE-2022-35583

Haukcode.DinkToPdf inherits a major security vulnerability from wkhtmltopdf that cannot be addressed:

CVE-2022-35583 - Critical SSRF Vulnerability (CVSS 9.8)

The wkhtmltopdf library (and all wrappers including Haukcode.DinkToPdf) is vulnerable to Server-Side Request Forgery (SSRF):

  • Attack Vector: Malicious HTML content can make the server fetch internal resources
  • AWS Metadata Attack: Can access http://169.254.169.254 to steal AWS credentials
  • Internal Network Access: Can scan and access internal services
  • Local File Inclusion: Can read local files via file:// protocol
  • Impact: Complete infrastructure takeover possible

There is NO fix for this vulnerability because wkhtmltopdf was abandoned and archived in 2023. The last release was version 0.12.6 in 2020.

IronPDF vs Haukcode.DinkToPdf: Feature Comparison

Understanding the architectural differences helps technical decision-makers evaluate the migration investment:

AspectHaukcode.DinkToPdfIronPDF
Underlying Enginewkhtmltopdf (Qt WebKit ~2015)Chromium (regularly updated)
Security StatusCVE-2022-35583 (CRITICAL, unfixable)Actively patched
Project StatusFork of abandoned projectActively developed
HTML5/CSS3LimitedFull support
JavaScriptLimited, insecureFull V8 engine
Native BinariesRequired (platform-specific)Self-contained
Thread SafetyRequires singleton patternThread-safe by design
SupportCommunity onlyProfessional support
UpdatesNone expectedRegular releases
LicenseMIT (Free)Commercial with free trial

Quick Start: Haukcode.DinkToPdf to IronPDF Migration

The migration can begin immediately with these foundational steps.

Step 1: Remove DinkToPdf and Native Binaries

Remove Haukcode.DinkToPdf NuGet packages:

# Remove NuGet packages
dotnet remove package DinkToPdf
dotnet remove package Haukcode.DinkToPdf
dotnet remove package Haukcode.WkHtmlToPdf-DotNet
# Remove NuGet packages
dotnet remove package DinkToPdf
dotnet remove package Haukcode.DinkToPdf
dotnet remove package Haukcode.WkHtmlToPdf-DotNet
SHELL

Delete native binaries from your project:

  • libwkhtmltox.dll (Windows)
  • libwkhtmltox.so (Linux)
  • libwkhtmltox.dylib (macOS)

Step 2: Install IronPDF

# Install IronPDF
dotnet add package IronPdf
# Install IronPDF
dotnet add package IronPdf
SHELL

Step 3: Update Namespaces

Replace DinkToPdf namespaces with IronPdf:

// Before (Haukcode.DinkToPdf)
using DinkToPdf;
using DinkToPdf.Contracts;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
// Before (Haukcode.DinkToPdf)
using DinkToPdf;
using DinkToPdf.Contracts;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
$vbLabelText   $csharpLabel

Step 4: Initialize License

Add license initialization at application startup:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Code Migration Examples

Basic HTML to PDF Conversion

The most fundamental operation reveals the complexity difference between these .NET PDF libraries.

Haukcode.DinkToPdf Approach:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");

        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");

        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf requires creating a SynchronizedConverter with PdfTools, constructing an HtmlToPdfDocument with nested GlobalSettings and Objects, adding an ObjectSettings with HtmlContent, calling converter.Convert() to get raw bytes, and manually writing to a file with File.WriteAllBytes().

IronPDF simplifies this to three lines: create a ChromePdfRenderer, call RenderHtmlAsPdf(), and use the built-in SaveAs() method.

For advanced HTML-to-PDF scenarios, see the HTML to PDF conversion guide.

Converting URLs to PDF

URL-to-PDF conversion shows similar pattern differences.

Haukcode.DinkToPdf Approach:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf uses the same document construction pattern with ObjectSettings.Page for URLs. IronPDF provides a dedicated RenderUrlAsPdf() method that clearly expresses intent.

Explore the URL to PDF documentation for authentication and custom header options.

Custom Page Settings

Configuring orientation, paper size, and margins requires different approaches.

Haukcode.DinkToPdf Approach:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.Letter,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("landscape.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.Letter,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("landscape.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");

        pdf.SaveAs("landscape.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");

        pdf.SaveAs("landscape.pdf");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf nests settings inside GlobalSettings with a separate MarginSettings object. IronPDF provides direct RenderingOptions properties with clear names like PaperSize, PaperOrientation, and individual margin properties.

Haukcode.DinkToPdf API to IronPDF Mapping Reference

This mapping accelerates migration by showing direct API equivalents:

Converter Class Mapping

Haukcode.DinkToPdfIronPDFNotes
SynchronizedConverterChromePdfRendererThread-safe, no singleton required
BasicConverterChromePdfRendererSame class handles both
PdfToolsN/ANot needed
IConverterN/AUse renderer directly

Document Configuration Mapping

Haukcode.DinkToPdfIronPDFNotes
HtmlToPdfDocumentMethod callUse RenderHtmlAsPdf() directly
GlobalSettingsRenderingOptionsSet before rendering
ObjectSettingsRenderingOptionsCombined into one
converter.Convert(doc)renderer.RenderHtmlAsPdf(html)Returns PdfDocument

GlobalSettings Property Mapping

GlobalSettings PropertyIronPDF PropertyNotes
ColorModeRenderingOptions.GrayScaleBoolean, set true for grayscale
OrientationRenderingOptions.PaperOrientationPortrait or Landscape
PaperSizeRenderingOptions.PaperSizeUse PdfPaperSize enum
Margins.TopRenderingOptions.MarginTopIn millimeters
Margins.BottomRenderingOptions.MarginBottomIn millimeters
Margins.LeftRenderingOptions.MarginLeftIn millimeters
Margins.RightRenderingOptions.MarginRightIn millimeters

ObjectSettings Property Mapping

ObjectSettings PropertyIronPDF EquivalentNotes
HtmlContentFirst parameter to RenderHtmlAsPdf()Direct parameter
Page (URL)renderer.RenderUrlAsPdf(url)Separate method
HeaderSettings.Right = "[page]"TextHeader.RightText = "{page}"Different placeholder syntax

Placeholder Syntax Migration

Haukcode.DinkToPdfIronPDFNotes
[page]{page}Current page number
[toPage]{total-pages}Total page count
[date]{date}Current date

Common Migration Issues and Solutions

Issue 1: Singleton Requirement

Haukcode.DinkToPdf: Requires SynchronizedConverter as a singleton due to thread safety issues with the native wkhtmltopdf binary.

Solution: IronPDF's ChromePdfRenderer is thread-safe by design—no singleton required:

// Before (DinkToPdf) - MUST be singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

// After (IronPDF) - Can be singleton or transient (both work)
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
// Before (DinkToPdf) - MUST be singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

// After (IronPDF) - Can be singleton or transient (both work)
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
$vbLabelText   $csharpLabel

Issue 2: Native Binary Dependencies

Haukcode.DinkToPdf: Requires platform-specific native libraries (libwkhtmltox.dll/so/dylib).

Solution: IronPDF is self-contained with no native binary dependencies. Delete these files after migration:

  • libwkhtmltox.dll (Windows)
  • libwkhtmltox.so (Linux)
  • libwkhtmltox.dylib (macOS)

Issue 3: Return Type Differences

Haukcode.DinkToPdf: converter.Convert() returns byte[] directly.

Solution: IronPDF returns a PdfDocument object with multiple output options:

var pdf = renderer.RenderHtmlAsPdf(html);
byte[] bytes = pdf.BinaryData;  // Get bytes
pdf.SaveAs("output.pdf");       // Or save directly
var pdf = renderer.RenderHtmlAsPdf(html);
byte[] bytes = pdf.BinaryData;  // Get bytes
pdf.SaveAs("output.pdf");       // Or save directly
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf: Uses square bracket syntax like [page] and [toPage].

Solution: Update to IronPDF's curly brace placeholders:

// Before (DinkToPdf)
HeaderSettings = { Right = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
    RightText = "Page {page} of {total-pages}"
};
// Before (DinkToPdf)
HeaderSettings = { Right = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
    RightText = "Page {page} of {total-pages}"
};
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf Migration Checklist

Pre-Migration Tasks

Audit your codebase to identify all DinkToPdf usage:

# Find DinkToPdf namespace usage
grep -r "using DinkToPdf\|using Haukcode" --include="*.cs" .

# Find converter usage
grep -r "SynchronizedConverter\|BasicConverter\|HtmlToPdfDocument" --include="*.cs" .

# Find native library loading
grep -r "wkhtmltopdf\|libwkhtmltox" --include="*.cs" --include="*.csproj" .

# Find GlobalSettings/ObjectSettings usage
grep -r "GlobalSettings\|ObjectSettings\|MarginSettings" --include="*.cs" .
# Find DinkToPdf namespace usage
grep -r "using DinkToPdf\|using Haukcode" --include="*.cs" .

# Find converter usage
grep -r "SynchronizedConverter\|BasicConverter\|HtmlToPdfDocument" --include="*.cs" .

# Find native library loading
grep -r "wkhtmltopdf\|libwkhtmltox" --include="*.cs" --include="*.csproj" .

# Find GlobalSettings/ObjectSettings usage
grep -r "GlobalSettings\|ObjectSettings\|MarginSettings" --include="*.cs" .
SHELL

Document current GlobalSettings and ObjectSettings configurations. Identify any native library loading code that can be removed.

Code Update Tasks

  1. Remove DinkToPdf NuGet packages
  2. Install IronPdf NuGet package
  3. Update namespace imports from DinkToPdf to IronPdf
  4. Replace SynchronizedConverter with ChromePdfRenderer
  5. Convert HtmlToPdfDocument patterns to direct method calls
  6. Convert GlobalSettings to RenderingOptions
  7. Convert ObjectSettings to RenderingOptions
  8. Update placeholder syntax ([page]{page}, [toPage]{total-pages})
  9. Add IronPDF license initialization at startup

Infrastructure Cleanup Tasks

  1. Delete native binaries (libwkhtmltox.*)
  2. Remove native library loading code
  3. Remove CustomAssemblyLoadContext if present
  4. Update Dependency Injection (singleton no longer required)
  5. Remove platform detection code for native binaries

Post-Migration Testing

After migration, verify these aspects:

  • Test HTML to PDF conversion
  • Test URL to PDF conversion
  • Verify page settings (size, orientation, margins)
  • Verify headers and footers with placeholders
  • Test with actual HTML templates
  • Performance test under load

Key Benefits of Migrating to IronPDF

Moving from Haukcode.DinkToPdf to IronPDF provides several critical advantages:

Security: Eliminates CVE-2022-35583 (SSRF) and other wkhtmltopdf vulnerabilities that will never be patched.

Modern Rendering Engine: Uses actively-updated Chromium instead of the abandoned Qt WebKit from 2015. Full HTML5, CSS3, and JavaScript support.

No Native Binaries: Self-contained library with no platform-specific DLLs to manage. Simplifies deployment across Windows, Linux, and macOS.

Thread Safety: No singleton requirement—use ChromePdfRenderer freely in any pattern including per-request instantiation.

Simpler API: Direct method calls (RenderHtmlAsPdf(), RenderUrlAsPdf()) instead of complex document object construction.

Active Development: As .NET 10 and C# 14 adoption increases through 2026, IronPDF's regular updates ensure compatibility with current and future .NET versions.

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