MIGRATION GUIDES How to Migrate from Rotativa to IronPDF in C# 커티스 차우 게시됨:2월 1, 2026 다운로드 IronPDF NuGet 다운로드 DLL 다운로드 윈도우 설치 프로그램 무료 체험 시작하기 LLM용 사본 LLM용 사본 LLM용 마크다운 형식으로 페이지를 복사하세요 ChatGPT에서 열기 ChatGPT에 이 페이지에 대해 문의하세요 제미니에서 열기 제미니에게 이 페이지에 대해 문의하세요 Grok에서 열기 Grok에게 이 페이지에 대해 문의하세요 혼란 속에서 열기 Perplexity에게 이 페이지에 대해 문의하세요 공유하다 페이스북에 공유하기 트위터에 공유하기 LinkedIn에 공유하기 URL 복사 이메일로 기사 보내기 Migrating from Rotativa to IronPDF addresses critical security vulnerabilities while modernizing your PDF generation workflow. This guide provides a complete, step-by-step migration path that eliminates the abandoned wkhtmltopdf dependency, enables support for modern CSS and JavaScript, and provides cross-platform compatibility beyond ASP.NET MVC. Why Migrate from Rotativa to IronPDF Understanding Rotativa Rotativa has long been a popular choice among developers for generating PDFs in C#. It leverages the wkhtmltopdf tool to convert HTML content into PDF format. Rotativa is an open-source library specifically designed for ASP.NET MVC applications. However, while it has attracted a significant audience, Rotativa's reliance on an outdated technology stack presents challenges that might not be immediately evident to every developer. At its core, Rotativa provides a simple way to integrate PDF generation into ASP.NET MVC projects, taking advantage of wkhtmltopdf for its backend functionalities. Critical Security Advisory Rotativa wraps wkhtmltopdf, which has CRITICAL UNPATCHED SECURITY VULNERABILITIES. Attribute Value CVE ID CVE-2022-35583 Severity CRITICAL (9.8/10) Attack Vector Network Status WILL NEVER BE PATCHED Affected ALL Rotativa versions wkhtmltopdf was officially abandoned in December 2022. The maintainers explicitly stated they will NOT fix security vulnerabilities. Every application using Rotativa is permanently exposed. How the Attack Works <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 Impact: Access AWS/Azure/GCP cloud metadata endpoints Steal internal API data and credentials Port scan internal networks Exfiltrate sensitive configuration The Technology Crisis Rotativa wraps wkhtmltopdf, which uses: Qt WebKit 4.8 (from 2012) No Flexbox support No CSS Grid support Broken JavaScript execution No ES6+ support Rotativa vs IronPDF Comparison Feature Rotativa IronPDF Project Compatibility ASP.NET MVC Only Any .NET Project Type (MVC, Razor Pages, Blazor, etc.) Maintenance Abandoned Actively Maintained Security Vulnerable due to wkhtmltopdf dependencies (CVE-2022-35583) Regular updates and security patches HTML Rendering Outdated WebKit Modern Chromium CSS3 Partial Supported Flexbox/Grid Not supported Supported JavaScript Unreliable Full ES6+ Razor Pages Not supported Supported Blazor Not supported Supported PDF Manipulation Not available Full Digital Signatures Not available Full PDF/A Compliance Not available Full Async/Await Synchronous only Full async Open Source Yes, MIT License No, Commercial License For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides modern Chromium rendering and cross-platform support that Rotativa cannot offer. Before You Start Prerequisites .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+ NuGet Access: Ability to install NuGet packages IronPDF License: Obtain your license key from ironpdf.com NuGet Package Changes # 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 Remove wkhtmltopdf Binaries Delete these files from your project: wkhtmltopdf.exe wkhtmltox.dll Any Rotativa/ folders These are the source of CVE-2022-35583. IronPDF needs no native binaries. License Configuration // 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 Complete API Reference Namespace Changes // 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 Core Class Mappings Rotativa Class IronPDF Equivalent ViewAsPdf ChromePdfRenderer ActionAsPdf ChromePdfRenderer.RenderUrlAsPdf() UrlAsPdf ChromePdfRenderer.RenderUrlAsPdf() Orientation enum PdfPaperOrientation enum Size enum PdfPaperSize enum Page Placeholder Conversion Rotativa Placeholder IronPDF Placeholder [page] {page} [topage] {total-pages} [date] {date} [time] {time} [title] {html-title} [sitepage] {url} Code Migration Examples Example 1: HTML to PDF Conversion Before (Rotativa): // 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>"; // Rotativa 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>"; // Rotativa requires returning a ViewAsPdf result from MVC controller return new ViewAsPdf() { ViewName = "PdfView", PageSize = Rotativa.AspNetCore.Options.Size.A4 }; } } } $vbLabelText $csharpLabel After (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 This example demonstrates the fundamental architectural difference. Rotativa requires returning a ViewAsPdf result from an MVC controller action, tying you to the ASP.NET MVC framework. The pattern only works within the MVC request pipeline and requires a Razor view to render. IronPDF works anywhere: console applications, web APIs, Blazor, Razor Pages, or any .NET project type. You call RenderHtmlAsPdf() with an HTML string and save the result. No MVC controller required, no view dependency. See the HTML to PDF documentation for comprehensive examples. Example 2: URL to PDF Conversion Before (Rotativa): // 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() { // Rotativa 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() { // Rotativa 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 After (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's UrlAsPdf class requires returning an ActionResult from an MVC controller. IronPDF's RenderUrlAsPdf() method can be called from any context and returns a PdfDocument object directly. The URL rendering uses modern Chromium instead of wkhtmltopdf's vulnerable and outdated WebKit engine. Learn more in our tutorials. Example 3: Headers and Footers with Page Numbers Before (Rotativa): // 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 After (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 uses CustomSwitches to pass command-line arguments to wkhtmltopdf, including header and footer configuration with placeholders like [page] and [toPage]. This string-based approach is error-prone and hard to validate at compile time. IronPDF uses strongly-typed TextHeaderFooter objects with properties like CenterText and DrawDividerLine. The placeholder syntax changes from [page] to {page} and from [toPage] to {total-pages}. Typed properties provide IntelliSense, compile-time checking, and no risk of typos. The MVC-Only Architecture Problem Rotativa was designed for ASP.NET MVC 5 and earlier: // ❌ Rotativa - 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 // ❌ Rotativa - 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 separates view rendering from PDF generation, which is actually more flexible—you can render any HTML, not just MVC views. Async Pattern Migration Rotativa blocks the thread; IronPDF supports full async/await: // ❌ Rotativa - Blocks the thread public ActionResult GeneratePdf() { return new ViewAsPdf("Report"); // This blocks the request thread until PDF is complete // Poor scalability under load } // ✅ IronPDF - Full async 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 } // ❌ Rotativa - Blocks the thread public ActionResult GeneratePdf() { return new ViewAsPdf("Report"); // This blocks the request thread until PDF is complete // Poor scalability under load } // ✅ IronPDF - Full async 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 New Capabilities After Migration After migrating to IronPDF, you gain capabilities that Rotativa cannot provide: PDF Merging var merged = PdfDocument.Merge(pdf1, pdf2, pdf3); merged.SaveAs("complete.pdf"); var merged = PdfDocument.Merge(pdf1, pdf2, pdf3); merged.SaveAs("complete.pdf"); $vbLabelText $csharpLabel Digital Signatures var signature = new PdfSignature("certificate.pfx", "password"); pdf.Sign(signature); var signature = new PdfSignature("certificate.pfx", "password"); pdf.Sign(signature); $vbLabelText $csharpLabel Password Protection pdf.SecuritySettings.UserPassword = "secret"; pdf.SecuritySettings.UserPassword = "secret"; $vbLabelText $csharpLabel Watermarks 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 Archival Compliance pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b); pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b); $vbLabelText $csharpLabel Modern CSS Support // 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 Migration Checklist Pre-Migration Identify all Rotativa usage in codebase Document CustomSwitches used for conversion to RenderingOptions Note header/footer placeholder syntax for conversion ([page] → {page}) Obtain IronPDF license key from ironpdf.com Package Changes Remove Rotativa and Rotativa.AspNetCore NuGet packages Delete wkhtmltopdf binaries (wkhtmltopdf.exe, wkhtmltox.dll) Install IronPdf NuGet package Code Changes Update namespace imports (using Rotativa; → using IronPdf;) Replace ViewAsPdf with ChromePdfRenderer + RenderHtmlAsPdf() Replace UrlAsPdf with RenderUrlAsPdf() Convert CustomSwitches to RenderingOptions properties Update placeholder syntax ([page] → {page}, [topage] → {total-pages}) Replace PageMargins with individual MarginTop/MarginBottom/MarginLeft/MarginRight Change to async pattern where appropriate Add license initialization at application startup Post-Migration Verify all PDF generation works correctly Compare PDF output quality (Chromium renders more accurately) Verify CSS rendering improvements (Flexbox/Grid now work) Test JavaScript execution (now reliable with Chromium) Verify security scan passes (no more CVE-2022-35583 flags) Update Docker configurations to remove wkhtmltopdf installation 커티스 차우 지금 바로 엔지니어링 팀과 채팅하세요 기술 문서 작성자 커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다. 커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다. 관련 기사 게시됨 2월 1, 2026 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. 더 읽어보기 게시됨 2월 1, 2026 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. 더 읽어보기 게시됨 2월 1, 2026 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...
게시됨 2월 1, 2026 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. 더 읽어보기
게시됨 2월 1, 2026 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. 더 읽어보기
게시됨 2월 1, 2026 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. 더 읽어보기