Przejdź do treści stopki
PRZEWODNIKI MIGRACJI

Jak przeprowadzić migrację z Rotativa do IronPDF w języku C#

Przejście zRotativanaIronPDFpozwala wyeliminować krytyczne luki w zabezpieczeniach, jednocześnie modernizując proces tworzenia plików PDF. Niniejszy przewodnik zawiera kompletną, krok po kroku ścieżkę migracji, która eliminuje porzuconą zależność od wkhtmltopdf, umożliwia obsługę nowoczesnego CSS i JavaScript oraz zapewnia kompatybilność międzyplatformową wykraczającą poza ASP.NET MVC.

Dlaczego warto przejść zRotativana IronPDF

Zrozumienie Rotativa

Rotativa od dawna cieszy się popularnością wśród programistów jako narzędzie do generowania plików PDF w języku C#. Wykorzystuje narzędzie wkhtmltopdf do konwersji treści HTML do formatu PDF.Rotativato biblioteka open source zaprojektowana specjalnie dla aplikacji ASP.NET MVC. Jednak mimo żeRotativaprzyciągnęła znaczną grupę odbiorców, jej poleganie na przestarzałym stosie technologicznym stwarza wyzwania, które mogą nie być od razu oczywiste dla każdego programisty.

ZasadniczoRotativazapewnia prosty sposób na zintegrowanie generowania plików PDF z projektami ASP.NET MVC, wykorzystując wkhtmltopdf do obsługi funkcji zaplecza.

Krytyczne ostrzeżenie dotyczące bezpieczeństwa

Rotativa wykorzystuje bibliotekę wkhtmltopdf, która zawiera KRYTYCZNE, NIEZŁATANE LUKI W BEZPIECZEŃSTWIE.

Atrybut Wartość
CVE ID CVE-2022-35583
Waga KLUCZOWE (9,8/10)
Wektor ataku Sieć
Status NIGDY NIE ZOSTANIE POPRAWIONE
Dotyczy WSZYSTKIE wersjeRotativa

wkhtmltopdf zostało oficjalnie wycofane w grudniu 2022 r. Twórcy wyraźnie oświadczyli, że NIE będą naprawiać luk w zabezpieczeniach. Każda aplikacja korzystająca zRotativajest stale widoczna.

Jak działa atak


<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

Wpływ:

  • Dostęp do punktów końcowych metadanych chmury AWS/Azure/GCP
  • Wykradanie wewnętrznych danych API i poświadczeń
  • Skanowanie portów w sieciach wewnętrznych
  • Wyciek poufnych danych konfiguracyjnych

Kryzys technologiczny

Rotativa wykorzystuje bibliotekę wkhtmltopdf, która korzysta z:

  • Qt WebKit 4.8 (z 2012 r.)
  • Brak obsługi Flexbox
  • Brak obsługi CSS Grid
  • Nieprawidłowe działanie kodu JavaScript
  • Brak obsługi ES6+

PorównanieRotativai IronPDF

Funkcja Rotativa IronPDF
Zgodność projektu Tylko ASP.NET MVC Dowolny typ projektu .NET (MVC, Razor Pages, Blazor itp.)
Konserwacja Porzucony Aktywnie utrzymywane
Bezpieczeństwo Podatność spowodowana zależnościami wkhtmltopdf (CVE-2022-35583) Regularne aktualizacje i poprawki bezpieczeństwa
Renderowanie HTML Przestarzały WebKit Nowoczesny Chromium
CSS3 Częściowe Obsługiwane
Flexbox/Grid Nieobsługiwane Obsługiwane
JavaScript Niewiarygodne Pełna obsługa ES6+
Razor Pages Nieobsługiwane Obsługiwane
Blazor Nieobsługiwane Obsługiwane
Manipulacja plikami PDF Niedostępne Pełna
Podpisy cyfrowe Niedostępne Pełna
Zgodność z PDF/A Niedostępne Pełna
Async/Await Tylko synchroniczne Pełna asynchroniczność
Open Source Tak, licencja MIT Nie, licencja komercyjna

Dla zespołów planujących wdrożenie .NET 10 i C# 14 w latach 2025 i 2026,IronPDFzapewnia nowoczesne renderowanie Chromium i obsługę wielu platform, którychRotativanie jest w stanie zaoferować.


Zanim zaczniesz

Wymagania wstępne

  1. Środowisko .NET: .NET Framework 4.6.2+ lub .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Dostęp do NuGet: Możliwość instalowania pakietów NuGet
  3. Licencja IronPDF: Uzyskaj klucz licencyjny na stronie ironpdf.com

Zmiany w pakiecie 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

Usuń pliki binarne wkhtmltopdf

Usuń te pliki z projektu:

  • wkhtmltopdf.exe
  • wkhtmltox.dll
  • Wszelkie foldery Rotativa/

Są to źródła CVE-2022-35583.IronPDFnie wymaga natywnych plików binarnych.

Konfiguracja licencji

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

Kompletna dokumentacija API

Zmiany w przestrzeni nazw

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

Mapowania klas podstawowych

KlasaRotativa OdpowiednikIronPDF
ViewAsPdf ChromePdfRenderer
ActionAsPdf ChromePdfRenderer.RenderUrlAsPdf()
UrlAsPdf ChromePdfRenderer.RenderUrlAsPdf()
Orientation enum PdfPaperOrientation enum
Size enum PdfPaperSize enum

Konwersja symboli zastępczych stron

Rotativa Placeholder IronPDF Placeholder
[page] {page}
[topage] {total-pages}
[date] {date}
[time] {time}
[title] {html-title}
[sitepage] {url}

Przykłady migracji kodu

Przykład 1: Konwersja HTML do PDF

Przed (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>";

            //Rotativarequires 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>";

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

Po (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

Ten przykład ilustruje podstawową różnicę architektoniczną.Rotativawymaga zwrotu wyniku ViewAsPdf z akcji kontrolera MVC, co wiąże użytkownika z frameworkiem ASP.NET MVC. Ten wzorzec działa wyłącznie w ramach potoku żądań MVC i wymaga widoku Razor do renderowania.

IronPDF działa wszędzie: w aplikacjach konsolowych, interfejsach API sieci Web, Blazor, Razor Pages lub dowolnym typie projektu .NET. Wywołujesz RenderHtmlAsPdf() z ciągiem HTML i zapisujesz wynik. Nie jest wymagany kontroler MVC, brak zależności od widoku. Kompleksowe przykłady można znaleźć w dokumentacji dotyczącej konwersji HTML do PDF.

Przykład 2: Konwersja adresów URL do formatu PDF

Przed (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()
        {
            //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.Core
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
$vbLabelText   $csharpLabel

Po (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

Klasa UrlAsPdf firmyRotativawymaga zwrotu ActionResult z kontrolera MVC. Metodę RenderUrlAsPdf() bibliotekiIronPDFmożna wywołać z dowolnego kontekstu, a zwraca ona bezpośrednio obiekt PdfDocument. Renderowanie adresów URL wykorzystuje nowoczesny silnik Chromium zamiast podatnego na ataki i przestarzałego silnika WebKit używanego przez wkhtmltopdf. Dowiedz się więcej z naszych samouczków.

Przykład 3: Nagłówki i stopki z numerami stron

Przed (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

Po (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 używa CustomSwitches do przekazywania argumentów wiersza poleceń do wkhtmltopdf, w tym konfiguracji nagłówków i stopek za pomocą symboli zastępczych, takich jak [page] i [toPage]. To podejście oparte na ciągach znaków jest podatne na błędy i trudne do zweryfikowania w czasie kompilacji.

IronPDF wykorzystuje obiekty silnie typowane TextHeaderFooter z właściwościami takimi jak CenterText i DrawDividerLine. Składnia symboli zastępczych zmienia się z [page] na {page} oraz z [toPage] na {total-pages}. Właściwości typowane zapewniają funkcję IntelliSense, sprawdzanie w czasie kompilacji oraz brak ryzyka wystąpienia literówek.


Problem architektury opartej wyłącznie na MVC

Rotativa została zaprojektowana dla ASP.NET MVC 5 i wcześniejszych wersji:

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

IronPDF oddziela renderowanie widoków od generowania plików PDF, co w rzeczywistości zapewnia większą elastyczność — można renderować dowolny kod HTML, a nie tylko widoki MVC.


Migracja wzorca asynchronicznego

Rotativa blokuje wątek;IronPDFobsługuje pełną funkcję 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- Pełna asynchroniczność 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- Pełna asynchroniczność 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- Pełna asynchroniczność 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

Nowe możliwości po migracji

Po migracji doIronPDFzyskujesz możliwości, którychRotativanie jest w stanie zapewnić:

Łączenie plików PDF

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

Podpisy cyfrowe

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

Ochrona hasłem

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

Znaki wodne

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

Zgodność z normą archiwizacji PDF/A

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

Obsługa nowoczesnego 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!
' 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 kontrolna migracji

Przed migracją

  • Zidentyfikuj wszystkie wystąpieniaRotativaw kodzie źródłowym
  • Dokument CustomSwitches używany do konwersji do RenderingOptions
  • Zwróć uwagę na składnię symboli zastępczych nagłówków/stopek do konwersji ([page]{page})
  • Uzyskaj klucz licencyjnyIronPDFze strony ironpdf.com

Zmiany w pakiecie

  • Usuń pakiety NuGet Rotativa i Rotativa.AspNetCore
  • Usuń pliki binarne wkhtmltopdf (wkhtmltopdf.exe, wkhtmltox.dll)
  • Zainstaluj pakiet NuGet IronPdf

Zmiany w kodzie

  • Zaktualizuj importy przestrzeni nazw (using Rotativa;using IronPdf;)
  • Zastąp ViewAsPdf przez ChromePdfRenderer + RenderHtmlAsPdf()
  • Zastąp UrlAsPdf przez RenderUrlAsPdf()
  • Zamień właściwości CustomSwitches na RenderingOptions
  • Zaktualizuj składnię symboli zastępczych ([page]{page}, [topage]{total-pages})
  • Zastąp PageMargins poszczególnymi MarginRight
  • W odpowiednich miejscach należy przejść na wzorzec asynchroniczny
  • Dodaj inicjalizację licencji podczas uruchamiania aplikacji

Po migracji

  • Sprawdź, czy generowanie plików PDF działa poprawnie
  • Porównaj jakość wydruku PDF (Chromium renderuje dokładniej)
  • Sprawdź ulepszenia w renderowaniu CSS (Flexbox/Grid teraz działają)
  • Testowanie wykonywania kodu JavaScript (obecnie działa niezawodnie w przeglądarce Chromium)
  • Sprawdź, czy skanowanie bezpieczeństwa zakończyło się pomyślnie (brak flag CVE-2022-35583)
  • Zaktualizuj konfiguracje Docker, aby usunąć instalację wkhtmltopdf

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie