IronPDF 2021:Chrome Rendering Engine EAP – PDF 生成的顛覆者!
DinkToPdf 封裝了 wkhtmltopdf,繼承了其所有的安全漏洞和技術限制。 了解這些問題對於評估遷移的緊迫性至關重要。
關鍵安全問題
DinkToPdf 繼承了 wkhtmltopdf 未修補的安全公告:
- CVE-2022-35583 (SSRF): 針對 wkhtmltopdf 0.12.6 的伺服器端請求偽造公告(CVSS 9.8 在 NVD 中; 被上游專案辯稱為應用程式側的輸入清理問題而不是程式庫錯誤)。 無論如何,這不會被修補。
- 歸檔項目:
wkhtmltopdf/wkhtmltopdf儲存庫於 2023 年 1 月 2 日被歸檔,整個wkhtmltopdfGitHub 組織於 2024 年 7 月 10 日被歸檔。 - 未來不再有安全補丁:任何已知或未來的漏洞將不會在上游修復。
技術問題
| 問題 | 影響 |
|---|---|
| 執行緒安全 | BasicConverter 僅為單執行緒; SynchronizedConverter 序列化呼叫,在負載下仍可能遭遇本機端崩潰 |
| 原生二進位檔 | 與平台特定的 libwkhtmltox 二進位檔複雜部署 |
| CSS限制 | 舊版 QtWebKit 分支—不支援現代的 Flexbox/網格布局 |
| JavaScript | 執行不一致,超時 |
| 渲染 | 過時的基於 QtWebKit 的引擎(wkhtmltopdf 0.12.6,最後發行於 2020 年 6 月) |
| 維護 | DinkToPdf 1.0.8 最後在 NuGet 上發行於 2017 年 4 月 18 日 |
架構比較
| 方面 | DinkToPdf | IronPDF |
|---|---|---|
| 安全性 | CVE-2022-35583 (SSRF),未修補/上游存在爭議 | 無已知的關鍵 CVE |
| 渲染引擎 | 舊版 QtWebKit 分支(wkhtmltopdf 0.12.6) | 現代 Chromium |
| 執行緒安全 | SynchronizedConverter 序列化呼叫; native-side crashes reported under load |
設計上具現成的執行緒安全性 |
| 本機相依性 | 平台特定的 libwkhtmltox 二進位檔 |
以 NuGet 套件管理 |
| CSS 支援 | 沒有現代 Flexbox/Grid | 完整支持 CSS3 |
| JavaScript | 有限且不一致的支持 | 支援 |
| 維護 | DinkToPdf 最後發行於 2017 年 4 月; wkhtmltopdf 組織歸檔於 2024 年 7 月 | 積極維護 |
功能比較
| 功能 | DinkToPdf | IronPDF |
|---|---|---|
| HTML轉PDF | ✅(過時的引擎) | ✅(Chromium) |
| URL到PDF | ✅ | ✅ |
| 自定義邊距 | ✅ | ✅ |
| 頁眉/頁腳 | ✅(有限) | ✅(完整 HTML) |
| CSS3 | ❌ 限制的 | ✅全面 |
| Flexbox/網格 | ❌ | ✅ |
| JavaScript | ⚠ 限制的 | ✅全面 |
| PDF操作 | ❌ | ✅ |
| 表單填寫 | ❌ | ✅ |
| 數位簽名 | ❌ | ✅ |
| 加密 | ❌ | ✅ |
| 浮水印 | ❌ | ✅ |
| 合併/分割 | ❌ | ✅ |
遷移前準備
前提條件
確保您的環境符合以下要求:
- .NET Framework 4.6.2+, .NET Core 3.1+, or .NET 5/6/7/8/9/10
- Visual Studio 2019+或VS Code與C#擴展
- NuGet包管理器存取 -IronPDF許可證金鑰(免費試用可在 ironpdf.com 獲得)
審核DinkToPdf使用情況
在您的解決方案目錄中運行這些命令,以識別所有DinkToPdf參考:
# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .
# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .
# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .
# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .
# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
預期的中斷變更
| 更改 | DinkToPdf | IronPDF | 影響 |
|---|---|---|---|
| 轉換器 | SynchronizedConverter(new PdfTools()) |
ChromePdfRenderer |
更簡單的實例化 |
| 文件 | HtmlToPdfDocument |
直接方法呼叫 | 沒有文件物件 |
| 設置 | GlobalSettings + ObjectSettings |
RenderingOptions |
單一選項物件 |
| 返回型別 | byte[] |
PdfDocument |
更強大的物件 |
| 二進位檔 | libwkhtmltox.dll/so |
無(托管) | 刪除本機檔案 |
| 執行緒安全 | BasicConverter 單執行緒; SynchronizedConverter 序列化 |
預設為執行緒安全 | 更簡單的程式碼 |
| DI | 需要單例 | 任何生命週期 | 靈活的 |
逐步遷移過程
步驟1:更新NuGet包
移除DinkToPdf並安裝 IronPDF:
# Remove DinkToPdf
dotnet remove package DinkToPdf
# Install IronPDF
dotnet add package IronPdf
# Remove DinkToPdf
dotnet remove package DinkToPdf
# Install IronPDF
dotnet add package IronPdf
步驟 2:移除本機二進位檔
從您的項目中刪除以下平台特定檔案:
libwkhtmltox.dll(Windows)libwkhtmltox.so(Linux)libwkhtmltox.dylib(macOS)
IronPDF 無本機相依性—全為托管程式碼。
步驟 3:更新命名空間參考
將DinkToPdf命名空間替換為 IronPDF:
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;
// Add this
using IronPdf;
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;
// Add this
using IronPdf;
Imports IronPdf
步驟 4:配置授權
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
完整 API 遷移參考
核心類映射
| DinkToPdf | IronPDF |
|---|---|
SynchronizedConverter |
ChromePdfRenderer |
BasicConverter |
ChromePdfRenderer |
PdfTools |
不需要 |
HtmlToPdfDocument |
不需要 |
GlobalSettings |
RenderingOptions |
ObjectSettings |
RenderingOptions |
MarginSettings |
個別邊距屬性 |
GlobalSettings 映射
| DinkToPdf GlobalSettings | IronPDF等價 |
|---|---|
ColorMode = ColorMode.Color |
預設(始終為彩色) |
Orientation = Orientation.Portrait |
PaperOrientation = PdfPaperOrientation.Portrait |
Orientation = Orientation.Landscape |
PaperOrientation = PdfPaperOrientation.Landscape |
PaperSize = PaperKind.A4 |
PaperSize = PdfPaperSize.A4 |
Margins = new MarginSettings() |
個別邊距屬性 |
MarginSettings 映射
| DinkToPdf Margins | IronPDF等價 |
|---|---|
Margins.Top = 10 |
MarginTop = 10 |
Margins.Bottom = 10 |
MarginBottom = 10 |
Margins.Left = 15 |
MarginLeft = 15 |
Margins.Right = 15 |
MarginRight = 15 |
程式碼遷移範例
基本 HTML 到 PDF
基本轉換顯示從DinkToPdf的冗長配置到IronPDF簡化 API 的重大簡化。
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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = {
New ObjectSettings() With {
.HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
.WebSettings = New WebSettings() With {
.DefaultEncoding = "utf-8"
}
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
End Sub
End Module
IronPDF實現:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF 將 20 行DinkToPdf配置減少到 4 行。 無 SynchronizedConverter,無 PdfTools,無 HtmlToPdfDocument,無 ObjectSettings—只需渲染和保存。 有關更多選項,請參閱HTML轉PDF文件。
URL 到 PDF 轉換
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);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.Page = "https://www.example.com"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("webpage.pdf", pdf)
End Sub
End Module
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");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
IronPDF 的 RenderUrlAsPdf 用直接方法呼叫取代了巢狀的 ObjectSettings.Page 配置。 有關更多選項,請參閱URL轉PDF文件。
自定義設置與橫向和邊距
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.A4,
Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom.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.A4,
Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom.pdf", pdf);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Landscape,
.PaperSize = PaperKind.A4,
.Margins = New MarginSettings() With {
.Top = 10,
.Bottom = 10,
.Left = 15,
.Right = 15
}
},
.Objects = {
New ObjectSettings() With {
.HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
.WebSettings = New WebSettings() With {
.DefaultEncoding = "utf-8"
}
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("custom.pdf", pdf)
End Sub
End Module
IronPDF實現:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 15
renderer.RenderingOptions.MarginRight = 15
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>")
pdf.SaveAs("custom.pdf")
End Sub
End Module
IronPDF 的 RenderingOptions 用統一的、流暢的 API 取代了 GlobalSettings 和 MarginSettings。 有關更多配置選項,請參閱渲染選項文件。
關鍵遷移注意事項
移除本機二進位檔
最重要的清理步驟是移除 wkhtmltopdf 本機二進位檔。IronPDF無本機相依性:
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
不需要單例
DinkToPdf 的文件指導是將 SynchronizedConverter 註冊為單例。IronPDF的 ChromePdfRenderer 在任何 DI 生命週期中皆為執行緒安全的:
//DinkToPdf- typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
//DinkToPdf- typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
' DinkToPdf - typically registered as singleton
services.AddSingleton(GetType(IConverter), New SynchronizedConverter(New PdfTools()))
' IronPDF - any lifetime works
services.AddScoped(Of ChromePdfRenderer)()
' Or just create inline:
Dim renderer As New ChromePdfRenderer()
更豐富的返回型別
DinkToPdf 返回 byte[]。IronPDF返回具有操作能力的 PdfDocument:
//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");
//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");
//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
' DinkToPdf returns byte()
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
Return File(pdf, "application/pdf")
' IronPDF returns PdfDocument
Dim pdfDocument = renderer.RenderHtmlAsPdf(html)
pdfDocument.SaveAs("output.pdf")
Return File(pdfDocument.BinaryData, "application/pdf")
完整的CSS3支援
在DinkToPdf中失敗的現代布局在IronPDF中能完美運作:
//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>"; // Broken!
//IronPDF- full support (modern Chromium)
var html = @"
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html); // Works!
//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>"; // Broken!
//IronPDF- full support (modern Chromium)
var html = @"
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html); // Works!
' DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
Dim html As String = "<div style='display: flex;'>...</div>" ' Broken!
' IronPDF- full support (modern Chromium)
Dim html As String = "
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>"
Dim pdf = renderer.RenderHtmlAsPdf(html) ' Works!
後遷移檢查清單
完成程式碼遷移後,請驗證以下內容:
- 運行所有單元測試以驗證PDF生成是否正常工作
- 測試多執行緒場景(
SynchronizedConverter路徑序列化呼叫,並在負載下容易發生本機端崩潰) - 比較 PDF 輸出質量(IronPDF 的 Chromium 渲染更佳)
- 驗證 CSS 渲染(Flexbox/網格現可用)
- 測試JavaScript執行(IronPDF 可靠)
- 更新 CI/CD 管道以移除 wkhtmltopdf 安裝
- 確認安全掃描通過(不再有 CVE-2022-35583 標誌)
- 從 Docker/部署腳本中移除本機二進位檔部署
其他資源
從DinkToPdf遷移到 IronPDF,使未修補的 wkhtmltopdf 攻擊面(CVE-2022-35583)、序列化的 SynchronizedConverter 並發模型、本機二進位檔部署和舊版 QtWebKit 渲染路徑退役。 切換到現代的 Chromium 引擎提供了完整的CSS3支援、可靠的JavaScript執行和積極維護的程式庫。

