MIGRATION GUIDES How to Migrate from Rotativa to IronPDF in C# Curtis Chau 發表日期:2026年2月1日 下載 IronPDF NuGet 下載 DLL 下載 Windows 安裝程式 開始免費試用 法學碩士副本 法學碩士副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在 Grok 中打開 向 Grok 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 從 旋轉 遷移到 IronPDF 可以解決關鍵的安全漏洞,同時實現 PDF 生成工作流程的現代化。 本指南提供了一個完整的、逐步的遷移路徑,消除了已棄用的 wkhtmltopdf 依賴項,實現了對現代 CSS 和 JavaScript 的支持,並提供了超越 ASP.NET MVC 的跨平台相容性。 為什麼要從 旋轉 遷移到 IronPDF 了解輪蟲 Rotativa 長期以來一直是開發人員在 C# 中產生 PDF 的熱門選擇。 它利用wkhtmltopdf工具將 HTML 內容轉換為 PDF 格式。 旋轉 是一個專為 ASP.NET MVC 應用程式設計的開源程式庫。 然而,儘管 旋轉 吸引了大量用戶,但它對過時技術堆疊的依賴也帶來了一些挑戰,這些挑戰可能不會立即被每個開發者所察覺。 Rotativa 的核心功能是提供一種簡單的方法,將 PDF 生成整合到 ASP.NET MVC 專案中,並利用wkhtmltopdf的後端功能。 關鍵安全公告 Rotativa 封裝了 wkhtmltopdf,而 wkhtmltopdf 存在尚未修復的嚴重安全漏洞。 屬性 價值 CVE ID CVE-2022-35583 嚴重程度 評分:9.8/10 攻擊向量 網路 地位 永遠不會修復 做作的 所有 旋轉 版本 wkhtmltopdf 已於 2022 年 12 月正式停止維護。維護者明確表示他們不會修復安全漏洞。 所有使用 旋轉 的應用程式將永久暴露在外。 攻擊原理 <iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe> <img src="http://internal-database:5432/admin" /> <iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe> <img src="http://internal-database:5432/admin" /> HTML 影響: 存取 AWS/Azure/GCP 雲端元資料端點 竊取內部 API 資料和憑證 連接埠掃描內部網路 洩漏敏感配置 技術危機 Rotativa wraps wkhtmltopdf,它使用: Qt WebKit 4.8(2012 年版) 不支援 Flexbox 不支援 CSS Grid JavaScript 執行失敗 不支援 ES6+ 旋轉 與 IronPDF 對比 特徵 旋轉 IronPDF 專案相容性 僅限 ASP.NET MVC 任何 .NET 專案類型(MVC、Razor Pages、Blazor 等) 維護 棄 積極維護 安全 由於 wkhtmltopdf 依賴項而存在漏洞 (CVE-2022-35583) 定期更新和安全性補丁 HTML渲染 過時的 WebKit 現代鉻 CSS3 部分的 全力支持 Flexbox/Grid 不支援 全力支持 JavaScript 不可靠 完整的 ES6+ Razor Pages 不支援 全力支持 布雷澤 不支援 全力支持 PDF 處理 無法使用 滿的 數位簽名 無法使用 滿的 PDF/A 合規性 無法使用 滿的 異步/等待 僅同步 完全異步 開源 是的,MIT許可證 不,商業許可證 對於計劃在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊,IronPDF 提供了 旋轉 無法提供的現代 Chromium 渲染和跨平台支援。 開始之前 先決條件 .NET 環境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+ NuGet 存取權限:能夠安裝 NuGet 套件 IronPDF 許可證:請從ironpdf.com取得您的許可證密鑰。 NuGet 套件變更 # Remove Rotativa dotnet remove package Rotativa dotnet remove package Rotativa.AspNetCore # Install IronPDF dotnet add package IronPdf # Remove Rotativa dotnet remove package Rotativa dotnet remove package Rotativa.AspNetCore # Install IronPDF dotnet add package IronPdf SHELL 移除 wkhtmltopdf 二進位文件 從項目中刪除以下文件: wkhtmltopdf.exe wkhtmltox.dll 任何Rotativa/資料夾 這些是 CVE-2022-35583 的來源。 IronPDF 不需要任何本機二進位。 許可證配置 // Add in Program.cs or Startup.cs IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; // Add in Program.cs or Startup.cs IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; $vbLabelText $csharpLabel 完整 API 參考 命名空間變更 // Before: Rotativa using Rotativa; using Rotativa.Options; using Rotativa.AspNetCore; // After: IronPDF using IronPdf; using IronPdf.Rendering; // Before: Rotativa using Rotativa; using Rotativa.Options; using Rotativa.AspNetCore; // After: IronPDF using IronPdf; using IronPdf.Rendering; $vbLabelText $csharpLabel 核心類別映射 扶輪社 IronPDF當量 筆記 ViewAsPdf ChromePdfRenderer 渲染 HTML ActionAsPdf ChromePdfRenderer.RenderUrlAsPdf() 渲染 URL UrlAsPdf ChromePdfRenderer.RenderUrlAsPdf() 渲染 URL Orientation枚舉 PdfPaperOrientation枚舉 方向 Size枚舉 PdfPaperSize枚舉 紙張尺寸 頁面佔位符轉換 輪蟲佔位符 IronPDF佔位符 [page] {page} [topage] {total-pages} [date] {date} [time] {time} [title] {html-title} [sitepage] {url} 程式碼遷移範例 範例 1:HTML 轉 PDF 之前(旋轉式): // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using System.Threading.Tasks; namespace RotativaExample { public class PdfController : Controller { public async Task<IActionResult> GeneratePdf() { var htmlContent = "<h1>Hello World</h1><p>This is a PDF document.</p>"; // 旋轉 requires returning a ViewAsPdf result from MVC controller return new ViewAsPdf() { ViewName = "PdfView", PageSize = Rotativa.AspNetCore.Options.Size.A4 }; } } } // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using System.Threading.Tasks; namespace RotativaExample { public class PdfController : Controller { public async Task<IActionResult> GeneratePdf() { var htmlContent = "<h1>Hello World</h1><p>This is a PDF document.</p>"; // 旋轉 requires returning a ViewAsPdf result from MVC controller return new ViewAsPdf() { ViewName = "PdfView", PageSize = Rotativa.AspNetCore.Options.Size.A4 }; } } } $vbLabelText $csharpLabel (IronPDF 之後): // NuGet: Install-Package IronPdf using IronPdf; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); var htmlContent = "<h1>Hello World</h1><p>This is a PDF document.</p>"; var pdf = renderer.RenderHtmlAsPdf(htmlContent); pdf.SaveAs("output.pdf"); Console.WriteLine("PDF generated successfully!"); } } } // NuGet: Install-Package IronPdf using IronPdf; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); var htmlContent = "<h1>Hello World</h1><p>This is a PDF document.</p>"; var pdf = renderer.RenderHtmlAsPdf(htmlContent); pdf.SaveAs("output.pdf"); Console.WriteLine("PDF generated successfully!"); } } } $vbLabelText $csharpLabel 這個例子展示了架構上的根本差異。 旋轉 要求從 MVC 控制器操作返回ViewAsPdf結果,這可讓您與 ASP.NET MVC 框架綁定。 此模式僅適用於 MVC 請求管道,並且需要 Razor 視圖進行渲染。 IronPDF 可在任何地方運作:控制台應用程式、Web API、Blazor、Razor Pages 或任何 .NET 專案類型。 你使用 HTML 字串呼叫RenderHtmlAsPdf()並儲存結果。 無需MVC控制器,沒有視圖依賴。 請參閱HTML 轉 PDF 文件以取得完整範例。 範例 2:URL 轉 PDF 之前(旋轉式): // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using System.Threading.Tasks; namespace RotativaExample { public class UrlPdfController : Controller { public async Task<IActionResult> ConvertUrlToPdf() { // 旋轉 works within MVC framework and returns ActionResult return new UrlAsPdf("https://www.example.com") { FileName = "webpage.pdf", PageSize = Rotativa.AspNetCore.Options.Size.A4, PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait }; } } } // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using System.Threading.Tasks; namespace RotativaExample { public class UrlPdfController : Controller { public async Task<IActionResult> ConvertUrlToPdf() { // 旋轉 works within MVC framework and returns ActionResult return new UrlAsPdf("https://www.example.com") { FileName = "webpage.pdf", PageSize = Rotativa.AspNetCore.Options.Size.A4, PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait }; } } } $vbLabelText $csharpLabel (IronPDF 之後): // NuGet: Install-Package IronPdf using IronPdf; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://www.example.com"); pdf.SaveAs("webpage.pdf"); Console.WriteLine("URL converted to PDF successfully!"); } } } // NuGet: Install-Package IronPdf using IronPdf; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://www.example.com"); pdf.SaveAs("webpage.pdf"); Console.WriteLine("URL converted to PDF successfully!"); } } } $vbLabelText $csharpLabel Rotativa 的UrlAsPdf類別需要從 MVC 控制器傳回ActionResult 。 IronPDF 的RenderUrlAsPdf()方法可以從任何上下文中調用,並直接傳回PdfDocument物件。 URL渲染採用的是現代的Chromium內核,而非wkhtmltopdf有安全漏洞且過時的WebKit引擎。更多資訊請參閱我們的教學。 範例 3:帶頁碼的頁首和頁尾 之前(旋轉式): // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using Rotativa.AspNetCore.Options; using System.Threading.Tasks; namespace RotativaExample { public class HeaderFooterController : Controller { public async Task<IActionResult> GeneratePdfWithHeaderFooter() { return new ViewAsPdf("Report") { PageSize = Size.A4, PageMargins = new Margins(20, 10, 20, 10), CustomSwitches = "--header-center \"Page Header\" --footer-center \"Page [page] of [toPage]\"" }; } } } // NuGet: Install-Package Rotativa.Core using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore; using Rotativa.AspNetCore.Options; using System.Threading.Tasks; namespace RotativaExample { public class HeaderFooterController : Controller { public async Task<IActionResult> GeneratePdfWithHeaderFooter() { return new ViewAsPdf("Report") { PageSize = Size.A4, PageMargins = new Margins(20, 10, 20, 10), CustomSwitches = "--header-center \"Page Header\" --footer-center \"Page [page] of [toPage]\"" }; } } } $vbLabelText $csharpLabel (IronPDF 之後): // NuGet: Install-Package IronPdf using IronPdf; using IronPdf.Rendering; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); renderer.RenderingOptions.TextHeader = new TextHeaderFooter() { CenterText = "Page Header", DrawDividerLine = true }; renderer.RenderingOptions.TextFooter = new TextHeaderFooter() { CenterText = "Page {page} of {total-pages}", DrawDividerLine = true }; var htmlContent = "<h1>Report Title</h1><p>Report content goes here.</p>"; var pdf = renderer.RenderHtmlAsPdf(htmlContent); pdf.SaveAs("report.pdf"); Console.WriteLine("PDF with headers and footers created successfully!"); } } } // NuGet: Install-Package IronPdf using IronPdf; using IronPdf.Rendering; using System; namespace IronPdfExample { class Program { static void Main(string[] args) { var renderer = new ChromePdfRenderer(); renderer.RenderingOptions.TextHeader = new TextHeaderFooter() { CenterText = "Page Header", DrawDividerLine = true }; renderer.RenderingOptions.TextFooter = new TextHeaderFooter() { CenterText = "Page {page} of {total-pages}", DrawDividerLine = true }; var htmlContent = "<h1>Report Title</h1><p>Report content goes here.</p>"; var pdf = renderer.RenderHtmlAsPdf(htmlContent); pdf.SaveAs("report.pdf"); Console.WriteLine("PDF with headers and footers created successfully!"); } } } $vbLabelText $csharpLabel Rotativa 使用CustomSwitches將命令列參數傳遞給 wkhtmltopdf,包括帶有[page]和[toPage]等佔位符的頁首和頁尾配置。 這種基於字串的方法容易出錯,而且在編譯時很難驗證。 IronPDF 使用強型別的TextHeaderFooter對象,具有CenterText和DrawDividerLine等屬性。 佔位符語法從[page]變成{page} ,從[toPage]變成{total-pages} 。 類型化屬性提供智慧感知、編譯時檢查,且不會出現拼字錯誤。 僅 MVC 架構的問題 Rotativa 是為 ASP.NET MVC 5 及更早版本設計的: // ❌ 旋轉 - Only works with classic MVC pattern public class InvoiceController : Controller { public ActionResult InvoicePdf(int id) { var model = GetInvoice(id); return new ViewAsPdf("Invoice", model); // Tied to MVC Views } } // Problems: // - No Razor Pages support // - No Blazor support // - No minimal APIs support // - No ASP.NET Core native integration // ❌ 旋轉 - Only works with classic MVC pattern public class InvoiceController : Controller { public ActionResult InvoicePdf(int id) { var model = GetInvoice(id); return new ViewAsPdf("Invoice", model); // Tied to MVC Views } } // Problems: // - No Razor Pages support // - No Blazor support // - No minimal APIs support // - No ASP.NET Core native integration $vbLabelText $csharpLabel IronPDF 將視圖渲染與 PDF 生成分離,這實際上更加靈活——您可以渲染任何 HTML,而不僅僅是 MVC 視圖。 非同步模式遷移 Rotativa 阻斷了線; IronPDF 完全支持 async/await: // ❌ 旋轉 - Blocks the thread public ActionResult GeneratePdf() { return new ViewAsPdf("Report"); // This blocks the request thread until PDF is complete // Poor scalability under load } // ✅ IronPDF - 完全異步 support public async Task<IActionResult> GeneratePdf() { var renderer = new ChromePdfRenderer(); var pdf = await renderer.RenderHtmlAsPdfAsync(html); return File(pdf.BinaryData, "application/pdf"); // Non-blocking, better scalability } // ❌ 旋轉 - Blocks the thread public ActionResult GeneratePdf() { return new ViewAsPdf("Report"); // This blocks the request thread until PDF is complete // Poor scalability under load } // ✅ IronPDF - 完全異步 support public async Task<IActionResult> GeneratePdf() { var renderer = new ChromePdfRenderer(); var pdf = await renderer.RenderHtmlAsPdfAsync(html); return File(pdf.BinaryData, "application/pdf"); // Non-blocking, better scalability } $vbLabelText $csharpLabel 遷移後的新功能 遷移到 IronPDF 後,您將獲得 旋轉 無法提供的功能: PDF合併 var merged = PdfDocument.Merge(pdf1, pdf2, pdf3); merged.SaveAs("complete.pdf"); var merged = PdfDocument.Merge(pdf1, pdf2, pdf3); merged.SaveAs("complete.pdf"); $vbLabelText $csharpLabel 數位簽名 var signature = new PdfSignature("certificate.pfx", "password"); pdf.Sign(signature); var signature = new PdfSignature("certificate.pfx", "password"); pdf.Sign(signature); $vbLabelText $csharpLabel 密碼保護 pdf.SecuritySettings.UserPassword = "secret"; pdf.SecuritySettings.UserPassword = "secret"; $vbLabelText $csharpLabel 水印 pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>"); pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>"); $vbLabelText $csharpLabel PDF/A 歸檔合規性 pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b); pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b); $vbLabelText $csharpLabel 現代 CSS 支持 // This now works (broke in Rotativa) var html = @" <div style='display: flex; justify-content: space-between;'> <div>Left</div> <div>Right</div> </div> <div style='display: grid; grid-template-columns: 1fr 1fr 1fr;'> <div>Col 1</div><div>Col 2</div><div>Col 3</div> </div>"; var pdf = renderer.RenderHtmlAsPdf(html); // Works! // This now works (broke in Rotativa) var html = @" <div style='display: flex; justify-content: space-between;'> <div>Left</div> <div>Right</div> </div> <div style='display: grid; grid-template-columns: 1fr 1fr 1fr;'> <div>Col 1</div><div>Col 2</div><div>Col 3</div> </div>"; var pdf = renderer.RenderHtmlAsPdf(html); // Works! $vbLabelText $csharpLabel 遷移清單 遷移前 識別程式碼庫中所有 旋轉 的使用情況 文檔 CustomSwitches 用於轉換為 RenderingOptions 注意頁首/頁尾佔位符的轉換語法( [page] → {page} ) 從ironpdf.com取得 IronPDF 許可證金鑰 軟體包變更 刪除Rotativa和Rotativa.AspNetCore NuGet 套件 刪除 wkhtmltopdf 二進位( wkhtmltopdf.exe 、 wkhtmltox.dll ) 安裝IronPdf NuGet 套件 程式碼更改 更新命名空間導入( using Rotativa; → using IronPdf; ) 將ViewAsPdf替換為ChromePdfRenderer + RenderHtmlAsPdf() 將UrlAsPdf替換為RenderUrlAsPdf() 將CustomSwitches轉換為RenderingOptions屬性 更新佔位符語法( [page] → {page} , [topage] → {total-pages} ) 將PageMargins替換為單獨的MarginTop / MarginBottom / MarginLeft / MarginRight 在適當情況下改為非同步模式 在應用程式啟動時新增許可證初始化 移民後 驗證所有 PDF 產生功能是否正常 對比PDF輸出品質(Chromium渲染更精準) 驗證 CSS 渲染改進(Flexbox/Grid 現在可以正常運作) 測試 JavaScript 執行(現在使用 Chromium 核心已穩定運行) 驗證安全掃描通過(不再有 CVE-2022-35583 標誌) 更新 Docker 設定以移除 wkhtmltopdf 安裝 Curtis Chau 立即與工程團隊聊天 技術撰稿人 Curtis Chau 擁有電腦科學學士學位(卡爾頓大學),專長於前端開發,精通 Node.js、TypeScript、JavaScript 和 React。Curtis 對製作直覺且美觀的使用者介面充滿熱情,他喜歡使用現代化的架構,並製作結構良好且視覺上吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 也有濃厚的興趣,他喜歡探索整合硬體與軟體的創新方式。在空閒時間,他喜歡玩遊戲和建立 Discord bots,將他對技術的熱愛與創意結合。 相關文章 發表日期 2026年2月1日 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 閱讀更多 發表日期 2026年2月1日 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 閱讀更多 發表日期 2026年2月1日 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 閱讀更多 How to Migrate from SAP Crystal Reports to IronPDF in C#How to Migrate from RawPrint to Iro...
發表日期 2026年2月1日 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 閱讀更多
發表日期 2026年2月1日 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 閱讀更多
發表日期 2026年2月1日 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 閱讀更多