Ir para o conteúdo do rodapé
GUIAS DE MIGRAçãO

Como migrar do Rotativa para o IronPDF em C#

A migração do Rotativa para 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 do Rotativa para o IronPDF?

Entendendo Rotativa

Rotativa tem sido, há muito tempo, uma escolha popular entre os desenvolvedores para gerar PDFs em C#. Ele utiliza 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 do Rotativa em uma pilha de tecnologia desatualizada apresenta desafios que podem não ser imediatamente evidentes para todos os desenvolvedores.

Em sua essência, o Rotativa oferece uma maneira simples de integrar a geração de PDFs 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 NUNCA SERÁ CORRIGIDO
Afetado TODAS as versões do Rotativa

O wkhtmltopdf foi oficialmente abandonado em dezembro de 2022. Os responsáveis ​​pela manutenção declararam explicitamente que NÃO corrigiriam as vulnerabilidades de segurança. Todas as aplicações que utilizam Rotativa ficam permanentemente expostas.

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" />
HTML

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 entre Rotativa e 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 que planejam a adoção do .NET 10 e do C# 14 até 2025 e 2026, o IronPDF oferece renderização moderna do Chromium e suporte multiplataforma que o Rotativa não pode oferecer.


Antes de começar

Pré-requisitos

  1. Ambiente .NET : .NET Framework 4.6.2+ ou .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Acesso ao NuGet : Capacidade de instalar pacotes NuGet.
  3. Licença do IronPDF : Obtenha sua chave de licença em IronPDF

Alterações no pacote 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

Remover binários do wkhtmltopdf

Exclua estes arquivos do seu projeto:

  • wkhtmltopdf.exe
  • wkhtmltox.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"
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Mapeamentos de Classes Principais

Aula Rotativa Equivalente ao IronPDF
ViewAsPdf ChromePdfRenderer
ActionAsPdf ChromePdfRenderer.RenderUrlAsPdf()
UrlAsPdf ChromePdfRenderer.RenderUrlAsPdf()
Orientation enum PdfPaperOrientation enum
Size enum PdfPaperSize enum

Conversão de espaço reservado da página

Espaço reservado para Rotativa 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.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
            };
        }
    }
}
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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Este exemplo demonstra a diferença arquitetônica fundamental. Rotativa exige o retorno de um resultado ViewAsPdf de uma ação de controlador MVC, vinculando você à estrutura 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.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
            };
        }
    }
}
' NuGet: Install-Package Rotativa.Core
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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

A classe UrlAsPdf do Rotativa requer o retorno de um ActionResult de um controlador MVC. O método RenderUrlAsPdf() do IronPDF pode ser chamado de qualquer contexto e retorna um objeto PdfDocument diretamente. 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.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]\""
            };
        }
    }
}
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,
                .PageMargins = New Margins(20, 10, 20, 10),
                .CustomSwitches = "--header-center ""Page Header"" --footer-center ""Page [page] of [toPage]"""
            }
        End Function
    End Class
End Namespace
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Rotativa usa CustomSwitches para passar argumentos de linha de comando para wkhtmltopdf, incluindo configuração de cabeçalho e rodapé com marcadores como [page] e [toPage]. Essa abordagem baseada em strings é propensa a erros e difícil de validar em tempo de compilação.

IronPDF usa objetos fortemente tipados TextHeaderFooter com propriedades como CenterText e DrawDividerLine. A sintaxe do marcador de posição 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
' ❌ Rotativa - Only works with classic MVC pattern
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
$vbLabelText   $csharpLabel

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 GeneratePdfAsync() 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
$vbLabelText   $csharpLabel

Novas funcionalidades após a migração

Após migrar para o IronPDF, você obtém recursos que o Rotativa nã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")
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

Proteção por senha

pdf.SecuritySettings.UserPassword = "secret";
pdf.SecuritySettings.UserPassword = "secret";
pdf.SecuritySettings.UserPassword = "secret"
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

Conformidade de arquivamento PDF/A

pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
$vbLabelText   $csharpLabel

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!
$vbLabelText   $csharpLabel

Lista de verificação para migração

Pré-migração

  • Identificar todas as utilizações de Rotativa na base de código.
  • Documentar CustomSwitches usados ​​para conversão em RenderingOptions
  • Observe a sintaxe do marcador de posição de cabeçalho/rodapé para conversão ([page]{page})
  • Obtenha a chave de licença do IronPDF em IronPDF

Alterações no pacote

  • Remover os pacotes NuGet Rotativa e Rotativa.AspNetCore
  • Excluir binários wkhtmltopdf (wkhtmltopdf.exe, wkhtmltox.dll)
  • Instale o pacote NuGet IronPdf

Alterações no código

  • Atualizar importações de namespace (using Rotativa;using IronPdf;)
  • Substitua ViewAsPdf por ChromePdfRenderer + RenderHtmlAsPdf()
  • Substitua UrlAsPdf por RenderUrlAsPdf()
  • Converter propriedades CustomSwitches para RenderingOptions
  • Atualizar sintaxe de espaço reservado ([page]{page}, [topage]{total-pages})
  • Substitua PageMargins pelos códigos individuais MarginRight
  • 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

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais

Equipe de suporte de ferro

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim