跳至页脚内容
迁移指南

从 Haukcode.DinkToPdf 迁移到 IronPDF

从 Haukcode.DinkToPdf 迁移到 IronPDF:完整的 C# 开发人员指南。

Haukcode.DinkToPdf 是之前流行的 DinkToPdf 库的分叉,它封装了 wkhtmltopdf 二进制文件,为 .NET 应用程序提供 HTML 到 PDF 的转换功能。 虽然 Haukcode.DinkToPdf 在原始 DinkToPdf 项目停滞后保持了与 .NET Core 的兼容性,但它继承了其上游依赖关系的关键安全漏洞。 底层 wkhtmltopdf 项目已于 2023 年 1 月归档,这意味着这些漏洞将永远无法修补。

本指南提供了从 Haukcode.DinkToPdf 到IronPDF的完整迁移路径,为需要从 PDF 生成工作流中消除安全风险的专业 .NET 开发人员提供了分步说明、代码比较和实用示例。

关键安全警告:CVE-2022-35583。

Haukcode.DinkToPdf 从 wkhtmltopdf 继承了一个无法修复的严重安全漏洞:

CVE-2022-35583 - 严重 SSRF 漏洞 (CVSS 9.8)

wkhtmltopdf 库(以及包括 Haukcode.DinkToPdf 在内的所有封装程序)存在服务器端请求伪造 (SSRF) 漏洞:

  • 攻击向量:恶意 HTML 内容可使服务器获取内部资源
  • AWS 元数据攻击:可访问 http://169.254.169.254 以窃取 AWS 凭据
  • 内部网络访问:可扫描和访问内部服务
  • 本地文件包含:可通过 file:// 协议读取本地文件
  • 影响:可能完全接管基础架构

此漏洞没有修复程序,因为 wkhtmltopdf 已于 2023 年废弃并归档。最后一次发布是 2020 年的 0.12.6 版。

IronPDFvs Haukcode.DinkToPdf:功能比较

了解架构差异有助于技术决策者评估迁移投资:

方面Haukcode.DinkToPdfIronPDF
底层引擎wkhtmltopdf (Qt WebKit ~2015)Chromium (定期更新)
安全状态CVE-2022-35583(CRITICAL,不可修复)积极修补
项目状态废弃项目的分叉积极开发
HTML5/CSS3有限的全面支持
JavaScript语言有限、不安全完整的 V8 引擎
本地二进制文件要求(特定平台)自成一体
线程安全需要单例模式线程安全设计
支持仅限社区专业支持
更新无预期定期发布
许可麻省理工学院(免费)免费试用版商业版

快速入门:Haukcode.DinkToPdf 到IronPDF的迁移。

迁移工作可以通过以下基本步骤立即开始。

步骤 1:删除 DinkToPdf 和本地二进制文件

删除 Haukcode.DinkToPdf NuGet 软件包:

# 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

从您的项目中删除本地二进制文件:

  • <代码>libwkhtmltox.dll</代码>(Windows)
  • libwkhtmltox.so (Linux)
  • <代码>libwkhtmltox.dylib</代码>(macOS)

步骤2:安装IronPDF

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

步骤 3:更新命名空间

用 IronPdf 替换 DinkToPdf 命名空间:

// 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
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

步骤 4:初始化许可证

在应用程序启动时添加许可证初始化:

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

代码迁移示例

基本 HTML 到 PDF 的转换

最基本的操作揭示了这些 .NET PDF 库之间的复杂性差异。

Haukcode.DinkToPdf 方法:

// 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);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 方法:

// 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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 要求使用<代码>PdfTools</代码创建一个 SynchronizedConverter, 使用嵌套的<代码>全局设置</代码和 Objects 构建一个 HtmlToPdfDocument, 添加一个<代码>对象设置</代码和 HtmlContent, 调用 converter.Convert() 来转换 HTML 文档。Convert()以获取原始字节,并使用 File.WriteAllBytes() 手动写入文件。

IronPDF 将其简化为三行:创建 ChromePdfRenderer, 调用 RenderHtmlAsPdf(), 并使用内置的 SaveAs() 方法。

有关 HTML 转 PDF 的高级应用场景,请参阅 HTML 转 PDF 指南

将 URL 转换为 PDF

URL 到 PDF 的转换也显示出类似的模式差异。

Haukcode.DinkToPdf 方法:

// 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);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 方法:

// 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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 使用与 ObjectSettings.Page 相同的文档构建模式来构建 URL。IronPDF提供了专门的 RenderUrlAsPdf() 方法,可以清晰地表达意图。

请浏览 URL to PDF 文档,了解身份验证和自定义页眉选项。

自定义页面设置

配置方向、纸张大小和页边距需要采用不同的方法。

Haukcode.DinkToPdf 方法:

// 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);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 方法:

// 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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 将设置嵌套在<代码>全局设置</代码与单独的 MarginSettings 对象中。IronPDF直接提供了名称清晰的<代码>渲染选项</代码属性,如 PaperSize, PaperOrientation 和各个页边距属性。

Haukcode.DinkToPdf API 到IronPDF的映射参考

这种映射通过显示直接的 API 对应关系来加速迁移:

转换器类映射

Haukcode.DinkToPdfIronPDF备注
<代码>同步转换器</代码<代码>ChromePdfRenderer</代码线程安全,无需单例
<代码>BasicConverter</代码<代码>ChromePdfRenderer</代码同一类别同时处理
<代码>PdfTools</代码不适用不需要
<代码>IConverter</代码不适用直接使用呈现器

文档配置映射

Haukcode.DinkToPdfIronPDF备注
<代码>HtmlToPdfDocument</代码方法调用直接使用 RenderHtmlAsPdf()
<代码>全局设置</代码<代码>渲染选项</代码渲染前设置
<代码>对象设置</代码<代码>渲染选项</代码合二为一
<代码>converter.Convert(doc)</代码<代码>renderer.RenderHtmlAsPdf(html)</代码返回 PdfDocument

GlobalSettings 属性映射

全局设置属性IronPdf 属性备注
<代码>ColorMode</代码<代码>RenderingOptions.GrayScale</代码布尔,设置 true 表示灰度
<代码>方向</代码<代码>RenderingOptions.PaperOrientation</代码<代码>肖像</代码>或<代码>风景</代码
<代码>纸张大小</代码<代码>RenderingOptions.PaperSize</代码使用 PdfPaperSize 枚举
<代码>Margins.Top</代码<代码>RenderingOptions.MarginTop</代码单位:毫米
<代码>Margins.Bottom</代码<代码>RenderingOptions.MarginBottom</代码单位:毫米
<代码>Margins.Left</代码<代码>RenderingOptions.MarginLeft</代码单位:毫米
<代码>Margins.Right</代码<代码>RenderingOptions.MarginRight</代码单位:毫米

对象设置属性映射

对象设置属性IronPdf 同等产品备注
<代码>HtmlContent</代码RenderHtmlAsPdf() 的第一个参数直接参数
<代码>页面</代码> (URL)<代码>renderer.RenderUrlAsPdf(url)</代码单独方法
<代码>HeaderSettings.Right = "[page]"</ 代码<代码>TextHeader.RightText = "{page}"</ 代码不同的占位符语法

占位符语法迁移

Haukcode.DinkToPdfIronPDF备注
<代码>[页面]</代码{page}当前页码
<代码>[toPage]</代码<代码>{总页数}</代码总页数
<代码>[日期]</代码<代码>{日期}</代码当前日期

常见迁移问题和解决方案

问题 1:单例需求

Haukcode.DinkToPdf:由于本地 wkhtmltopdf 二进制程序的线程安全问题,需要<代码>同步转换器</代码作为单例。

解决方案:IronPDF的<代码>ChromePdfRenderer</代码在设计上是线程安全的--无需单例:

// 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!
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

问题 2:本地二进制依赖关系

Haukcode.DinkToPdf:需要特定平台的本地库(libwkhtmltox.dll/so/dylib)。

解决方案:IronPDF是独立的,没有本地二进制依赖关系。 迁移后删除这些文件:

  • <代码>libwkhtmltox.dll</代码>(Windows)
  • libwkhtmltox.so (Linux)
  • <代码>libwkhtmltox.dylib</代码>(macOS)

问题 3:返回类型差异

Haukcode.DinkToPdf:converter.Convert()直接返回字节[]

解决方案:IronPDF返回一个具有多个输出选项的 PdfDocument 对象:

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
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

问题 4:页眉/页脚占位符语法

Haukcode.DinkToPdf:使用方括号语法,如<代码>[页面]</代码和<代码>[toPage]</代码。

解决方案:更新IronPDF的大括号占位符:

// 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}"
};
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 迁移检查表

迁移前任务

审核您的代码库,确定所有 DinkToPdf 的使用情况:

# 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

记录当前的<代码>全局设置</代码和<代码>对象设置</代码配置。 确定任何可以删除的本地库加载代码。

代码更新任务

1.删除 DinkToPdf NuGet 软件包 2.安装 IronPdf NuGet 软件包 3.将名称空间导入从 DinkToPdf 更新为 IronPdf 4.将<代码>同步转换器</代码替换为 ChromePdfRenderer 5.将<代码>HtmlToPdfDocument</代码模式转换为直接方法调用 6.将<代码>全局设置</代码转换为 RenderingOptions 7.将<代码>对象设置</代码转换为 RenderingOptions 8.更新占位符语法([page]{page},<代码>[toPage]</代码→ {total-pages}) 9.在启动时添加 IronPdf 许可证初始化功能

基础架构清理任务

1.删除本地二进制文件 (libwkhtmltox.*) 2.删除本地库加载代码 3.如果存在,移除 CustomAssemblyLoadContext 4.更新依赖注入(不再需要单例) 5.删除本地二进制文件的平台检测代码

迁移后测试

迁移后,验证这些方面:

  • 测试 HTML 到 PDF 的转换
  • 测试 URL 到 PDF 的转换
  • 验证页面设置(大小、方向、页边距)
  • 用占位符验证页眉和页脚
  • 使用实际的 HTML 模板进行测试
  • 负载下的性能测试

迁移到IronPDF的主要优势

从 Haukcode.DinkToPdf 迁移到IronPDF有几个关键优势:

安全性:消除 CVE-2022-35583 (SSRF) 和其他永远无法修补的 wkhtmltopdf 漏洞。

现代渲染引擎:使用主动更新的 Chromium,而不是 2015 年废弃的 Qt WebKit。完全支持 HTML5、CSS3 和 JavaScript。

无本地二进制文件:自带库,无需管理特定平台的 DLL。 简化在 Windows、Linux 和 macOS 上的部署。

线程安全:无单例要求--以任何模式(包括按请求实例化)自由使用<代码>ChromePdfRenderer</代码。

更简单的 API:直接调用方法(RenderHtmlAsPdf(), RenderUrlAsPdf()),而不是复杂的文档对象构造。

主动开发:随着 .NET 10 和 C# 14 在 2026 年之前的采用率不断提高,IronPDF 的定期更新可确保与当前和未来的 .NET 版本兼容。

结论

Haukcode.DinkToPdf 作为 DinkToPdf 项目的延续,保持了基于 wkhtmltopdf 的 PDF 生成的 .NET Core 兼容性。 然而,底层的 wkhtmltopdf 二进制文件已于 2023 年归档,导致 CVE-2022-35583 等关键安全漏洞永久未得到修补。 每天都有应用程序继续使用 Haukcode.DinkToPdf,基础架构仍然面临 SSRF 攻击的风险。

IronPDF 提供了一个现代、安全的替代方案,其 Chromium 渲染引擎可处理当代网络标准。 迁移路径简单明了:移除 DinkToPdf 包和本地二进制文件,用直接渲染方法取代文档构建,并更新占位符语法。

立即开始迁移,免费试用 IronPDF,消除基于 wkhtmltopdf 的解决方案固有的安全漏洞。

有关全面的实施指导,请浏览 IronPDF 文档教程

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。