Como migrar do Rotativa para o IronPDF em C#
A migração doRotativapara o IronPDF resolve vulnerabilidades de segurança críticas e moderniza seu fluxo de trabalho de geração de PDFs. Este guia fornece um caminho de migração completo, passo a passo, que elimina a dependência abandonada do wkhtmltopdf, habilita o suporte para CSS e JavaScript modernos e oferece compatibilidade entre plataformas além do ASP.NET MVC.
Por que migrar doRotativapara o IronPDF?
Entendendo Rotativa
Rotativa tem sido, há muito tempo, uma escolha popular entre os desenvolvedores para gerar PDFs em C#. Ele aproveita a ferramenta wkhtmltopdf para converter conteúdo HTML em formato PDF.Rotativaé uma biblioteca de código aberto projetada especificamente para aplicações ASP.NET MVC. No entanto, embora tenha atraído um público significativo, a dependência doRotativaem uma pilha de tecnologia desatualizada apresenta desafios que podem não ser imediatamente evidentes para todos os desenvolvedores.
Em seu núcleo, oRotativaproporciona uma maneira simples de integrar a geração de PDF em projetos ASP.NET MVC, aproveitando o wkhtmltopdf para suas funcionalidades de backend.
Aviso de Segurança Crítica
Rotativa utiliza o wkhtmltopdf, que possui VULNERABILIDADES DE SEGURANÇA CRÍTICAS NÃO CORRIGIDAS.
| Atributo | Valor |
|---|---|
| ID CVE | CVE-2022-35583 |
| Gravidade | CRÍTICO (9,8/10) |
| Vetor de ataque | Rede |
| Status | Nenhuma versão fixa (binário do wkhtmltopdf arquivado) |
| Afetado | Todas as versões doRotativaagrupam wkhtmltopdf 0.12.6 |
O repositório GitHub do wkhtmltopdf foi arquivado (somente leitura) em 2 de janeiro de 2023. A página de status do mantenedor observa que o projeto depende do Qt 4 (não suportado desde 2015) e um branch do WebKit de 2012, e adverte explicitamente contra o uso dele com HTML não confiável.CVE-2022-35583não tem versão fixa, então qualquer aplicativo usandoRotativaestá exposto a menos que as entradas HTML sejam totalmente sanitizadas a montante.
Como funciona o ataque
<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" />
Impacto:
- Acessar endpoints de metadados da nuvem AWS/Azure/GCP
- Roubar dados e credenciais da API interna
- Varredura de portas em redes internas
- Configuração sensível à exfiltração
A crise tecnológica
Rotativa encapsula o wkhtmltopdf, que utiliza:
- Qt WebKit 4.8 (a partir de 2012)
- Sem suporte para Flexbox
- Sem suporte para CSS Grid
- Execução de JavaScript interrompida
- Sem suporte para ES6+
Comparação entreRotativae IronPDF
| Recurso | Rotativa | IronPDF |
|---|---|---|
| Compatibilidade do projeto | Somente ASP.NET MVC | Qualquer tipo de projeto .NET (MVC, Razor Pages, Blazor, etc.) |
| Manutenção | Abandonado | Mantido ativamente |
| Segurança | Vulnerável devido a dependências do wkhtmltopdf (CVE-2022-35583) | Atualizações regulares e correções de segurança. |
| Renderização HTML | WebKit desatualizado | Cromo moderno |
| CSS3 | Parcial | Apoiado |
| Flexbox/Grade | Não suportado | Apoiado |
| JavaScript | Não confiável | ES6+ completo |
| Páginas de Razor | Não suportado | Apoiado |
| Blazor | Não suportado | Apoiado |
| Manipulação de PDF | Não disponível | Completo |
| Assinaturas digitais | Não disponível | Completo |
| Conformidade com PDF/A | Não disponível | Completo |
| Assíncrono/Aguardar | Somente síncrono | Totalmente assíncrono |
| Código aberto | Sim, Licença MIT | Não, Licença Comercial |
Para equipes tendo como alvo as versões atuais do .NET,IronPDF oferece renderização moderna Chromium e suporte cross-platform queRotativanão pode oferecer.
Antes de começar
Pré-requisitos
- Ambiente .NET : .NET Framework 4.6.2+ ou .NET Core 3.1+ / .NET 5/6/7/8/9+
- Acesso ao NuGet : Capacidade de instalar pacotes NuGet.
- Licença do IronPDF: Obtenha sua chave de licença em IronPDF
Alterações no pacote NuGet
O pacote original Rotativa tem como alvo o ASP.NET MVC 5 clássico (último lançamento v1.7.3, 29-09-2017). O fork da comunidade Rotativa.AspNetCore (webgio) alcançou a versão v1.4.0 em 06-11-2024 e suporta do .NET Core 3.1 ao .NET 8 — mas ambos os pacotes ainda fornecem o binário wkhtmltopdf 0.12.6 (último lançamento upstream em junho de 2020).
# 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
Remover binários do wkhtmltopdf
Exclua estes arquivos do seu projeto:
wkhtmltopdf.exewkhtmltox.dll- Quaisquer pastas
Rotativa/
Essas são as fontes da vulnerabilidade CVE-2022-35583. O IronPDF não precisa de binários nativos.
Configuração de licença
// 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";
' Add in Program.vb or Startup.vb
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Referência completa da API
Alterações de namespace
// 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;
' Before: Rotativa
Imports Rotativa
Imports Rotativa.Options
Imports Rotativa.AspNetCore
' After: IronPDF
Imports IronPdf
Imports IronPdf.Rendering
Mapeamentos de Classes Principais
| AulaRotativa | Equivalente ao IronPDF |
|---|---|
ViewAsPdf |
ChromePdfRenderer |
ActionAsPdf |
ChromePdfRenderer.RenderUrlAsPdf() |
UrlAsPdf |
ChromePdfRenderer.RenderUrlAsPdf() |
enum Orientation |
enum PdfPaperOrientation |
enum Size |
enum PdfPaperSize |
Conversão de espaço reservado da página
| Espaço reservado paraRotativa | Espaço reservado para IronPDF |
|---|---|
[page] |
{page} |
[topage] |
{total-pages} |
[date] |
{date} |
[time] |
{time} |
[title] |
{html-title} |
[sitepage] |
{url} |
Exemplos de migração de código
Exemplo 1: Conversão de HTML para PDF
Antes (Rotativa):
// NuGet: Install-Package Rotativa.AspNetCore
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>";
//Rotativarequires returning a ViewAsPdf result from MVC controller
return new ViewAsPdf()
{
ViewName = "PdfView",
PageSize = Rotativa.AspNetCore.Options.Size.A4
};
}
}
}
// NuGet: Install-Package Rotativa.AspNetCore
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>";
//Rotativarequires returning a ViewAsPdf result from MVC controller
return new ViewAsPdf()
{
ViewName = "PdfView",
PageSize = Rotativa.AspNetCore.Options.Size.A4
};
}
}
}
Imports Microsoft.AspNetCore.Mvc
Imports Rotativa.AspNetCore
Imports System.Threading.Tasks
Namespace RotativaExample
Public Class PdfController
Inherits Controller
Public Async Function GeneratePdf() As Task(Of IActionResult)
Dim htmlContent As String = "<h1>Hello World</h1><p>This is a PDF document.</p>"
' Rotativa requires returning a ViewAsPdf result from MVC controller
Return New ViewAsPdf() With {
.ViewName = "PdfView",
.PageSize = Rotativa.AspNetCore.Options.Size.A4
}
End Function
End Class
End Namespace
Após (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!");
}
}
}
Imports IronPdf
Imports System
Namespace IronPdfExample
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
Dim htmlContent = "<h1>Hello World</h1><p>This is a PDF document.</p>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF generated successfully!")
End Sub
End Class
End Namespace
Este exemplo demonstra a diferença arquitetônica fundamental.Rotativaexige retornar um resultado ViewAsPdf de uma ação de controlador MVC, vinculando você ao framework ASP.NET MVC. Esse padrão funciona apenas dentro do pipeline de requisição MVC e requer uma view Razor para ser renderizada.
O IronPDF funciona em qualquer lugar: aplicativos de console, APIs da web, Blazor, Razor Pages ou qualquer tipo de projeto .NET . Você chama RenderHtmlAsPdf() com uma string HTML e salva o resultado. Não requer controlador MVC, nem dependência de visualização. Consulte a documentação de conversão de HTML para PDF para obter exemplos completos.
Exemplo 2: Conversão de URL para PDF
Antes (Rotativa):
// NuGet: Install-Package Rotativa.AspNetCore
using Microsoft.AspNetCore.Mvc;
using Rotativa.AspNetCore;
using System.Threading.Tasks;
namespace RotativaExample
{
public class UrlPdfController : Controller
{
public async Task<IActionResult> ConvertUrlToPdf()
{
//Rotativaworks 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.AspNetCore
using Microsoft.AspNetCore.Mvc;
using Rotativa.AspNetCore;
using System.Threading.Tasks;
namespace RotativaExample
{
public class UrlPdfController : Controller
{
public async Task<IActionResult> ConvertUrlToPdf()
{
//Rotativaworks 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
};
}
}
}
Imports Microsoft.AspNetCore.Mvc
Imports Rotativa.AspNetCore
Imports System.Threading.Tasks
Namespace RotativaExample
Public Class UrlPdfController
Inherits Controller
Public Async Function ConvertUrlToPdf() As Task(Of IActionResult)
' Rotativa works within MVC framework and returns ActionResult
Return New UrlAsPdf("https://www.example.com") With {
.FileName = "webpage.pdf",
.PageSize = Rotativa.AspNetCore.Options.Size.A4,
.PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait
}
End Function
End Class
End Namespace
Após (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!");
}
}
}
Imports IronPdf
Imports System
Namespace IronPdfExample
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("URL converted to PDF successfully!")
End Sub
End Class
End Namespace
A classe UrlAsPdf deRotativaexige o retorno de um ActionResult de um controlador MVC. O método RenderUrlAsPdf() do IronPDF pode ser chamado de qualquer contexto e retorna diretamente um objeto PdfDocument. A renderização de URLs utiliza o Chromium moderno em vez do mecanismo WebKit vulnerável e desatualizado do wkhtmltopdf. Saiba mais em nossos tutoriais .
Exemplo 3: Cabeçalhos e rodapés com números de página
Antes (Rotativa):
// NuGet: Install-Package Rotativa.AspNetCore
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,
// Margins(top, right, bottom, left)
PageMargins = new Margins(20, 10, 20, 10),
CustomSwitches = "--header-center \"Page Header\" --footer-center \"Page [page] of [topage]\""
};
}
}
}
// NuGet: Install-Package Rotativa.AspNetCore
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,
// Margins(top, right, bottom, left)
PageMargins = new Margins(20, 10, 20, 10),
CustomSwitches = "--header-center \"Page Header\" --footer-center \"Page [page] of [topage]\""
};
}
}
}
Imports Microsoft.AspNetCore.Mvc
Imports Rotativa.AspNetCore
Imports Rotativa.AspNetCore.Options
Imports System.Threading.Tasks
Namespace RotativaExample
Public Class HeaderFooterController
Inherits Controller
Public Async Function GeneratePdfWithHeaderFooter() As Task(Of IActionResult)
Return New ViewAsPdf("Report") With {
.PageSize = Size.A4,
' Margins(top, right, bottom, left)
.PageMargins = New Margins(20, 10, 20, 10),
.CustomSwitches = "--header-center ""Page Header"" --footer-center ""Page [page] of [topage]"""
}
End Function
End Class
End Namespace
Após (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!");
}
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Namespace IronPdfExample
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
.CenterText = "Page Header",
.DrawDividerLine = True
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter() With {
.CenterText = "Page {page} of {total-pages}",
.DrawDividerLine = True
}
Dim htmlContent = "<h1>Report Title</h1><p>Report content goes here.</p>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("report.pdf")
Console.WriteLine("PDF with headers and footers created successfully!")
End Sub
End Class
End Namespace
Rotativa usa CustomSwitches para passar argumentos de linha de comando para wkhtmltopdf, incluindo a configuração de cabeçalho e rodapé com placeholders como [page] e [topage]. Essa abordagem baseada em strings é propensa a erros e difícil de validar em tempo de compilação.
IronPDF utiliza objetos TextHeaderFooter fortemente tipados com propriedades como CenterText e DrawDividerLine. A sintaxe de placeholder muda de [page] para {page} e de [topage] para {total-pages}. Propriedades tipadas oferecem IntelliSense, verificação em tempo de compilação e eliminam o risco de erros de digitação.
O problema da arquitetura baseada exclusivamente em MVC
Rotativa foi projetado para ASP.NET MVC 5 e versões anteriores:
// ❌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
Imports System.Web.Mvc
Public Class InvoiceController
Inherits Controller
Public Function InvoicePdf(id As Integer) As ActionResult
Dim model = GetInvoice(id)
Return New ViewAsPdf("Invoice", model) ' Tied to MVC Views
End Function
End Class
' Problems:
' - No Razor Pages support
' - No Blazor support
' - No minimal APIs support
' - No ASP.NET Core native integration
O IronPDF separa a renderização da visualização da geração do PDF, o que na verdade é mais flexível — você pode renderizar qualquer HTML, não apenas visualizações MVC.
Migração de padrão assíncrono
Rotativa bloqueia a rosca; O IronPDF oferece suporte completo a 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- Totalmente assíncrono 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- Totalmente assíncrono 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 Function GeneratePdf() As ActionResult
Return New ViewAsPdf("Report")
' This blocks the request thread until PDF is complete
' Poor scalability under load
End Function
' ✅IronPDF- Totalmente assíncrono support
Public Async Function GeneratePdf() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
' Non-blocking, better scalability
End Function
Novas funcionalidades após a migração
Após migrar para o IronPDF, você obtém recursos que oRotativanão pode oferecer:
Fusão de PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("complete.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("complete.pdf");
Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
merged.SaveAs("complete.pdf")
Assinaturas digitais
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
Dim signature = New PdfSignature("certificate.pfx", "password")
pdf.Sign(signature)
Proteção por senha
pdf.SecuritySettings.UserPassword = "secret";
pdf.SecuritySettings.UserPassword = "secret";
pdf.SecuritySettings.UserPassword = "secret"
Marcas d'água
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
Conformidade de arquivamento PDF/A
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
Suporte a CSS moderno
// 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!
' This now works (broke in Rotativa)
Dim html As String = "
<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>"
Dim pdf = renderer.RenderHtmlAsPdf(html) ' Works!
Lista de verificação para migração
Pré-migração
- Identificar todas as utilizações deRotativana base de código.
- Documentar CustomSwitches usados para conversão em RenderingOptions
- Nota acerca do sintaxe de placeholder para cabeçalho/rodapé na conversão (
[page]→{page}) - Obtenha a chave de licença do IronPDF em IronPDF
Alterações no pacote
- Remova os pacotes NuGet
RotativaeRotativa.AspNetCore - Exclua os binários do wkhtmltopdf (
wkhtmltopdf.exe,wkhtmltox.dll) - Instale o pacote NuGet
IronPdf
Alterações no código
- Atualize as importações de namespace (
using Rotativa;→using IronPdf;) - Substitua
ViewAsPdfporChromePdfRenderer+RenderHtmlAsPdf() - Substitua
UrlAsPdfporRenderUrlAsPdf() - Converta
CustomSwitchespara propriedadesRenderingOptions - Atualize a sintaxe de placeholder (
[page]→{page},[topage]→{total-pages}) - Substitua
PageMarginsporMarginRightindividuais - Alterar para o padrão assíncrono quando apropriado.
- Adicionar inicialização de licença na inicialização do aplicativo
Pós-migração
- Verifique se a geração de PDFs funciona corretamente.
- Comparar a qualidade de saída do PDF (o Chromium renderiza com mais precisão)
- Verificar melhorias na renderização de CSS (Flexbox/Grid agora funcionam)
- Teste a execução de JavaScript (agora confiável com o Chromium)
- Verificar se a verificação de segurança foi aprovada (sem mais sinalizadores CVE-2022-35583)
- Atualize as configurações do Docker para remover a instalação do wkhtmltopdf

