Jak konwertować widoki na pliki PDF w ASP.NET Core MVC | IronPDF

Jak konwertować widoki na pliki PDF w C# ASP.NET Core MVC

This article was translated from English: Does it need improvement?
Translated
View the article in English

Konwertuj widoki ASP.NET Core MVC do PDF za pomocą metody RenderRazorViewToPdf IronPDF, która przekształca pliki .cshtml w wysokiej jakości dokumenty PDF za pomocą jednej linii kodu w aplikacji MVC.

Widok to komponent w .NET Framework używany do generowania znaczników HTML w aplikacjach internetowych. Jest to część wzorca Model-View-Controller (MVC), powszechnie stosowanego w aplikacjach ASP.NET MVC i ASP.NET Core MVC. Widoki są odpowiedzialne za prezentowanie danych użytkownikom poprzez dynamiczne renderowanie treści HTML. Widoki zazwyczaj wykorzystują składnię Razor, czyli składnię znaczników służącą do osadzania kodu serwerowego w stronach internetowych, co czyni je potężnymi narzędziami do tworzenia dokumentów PDF opartych na danych.

Szybki start: Konwersja CSHTML do formatu PDF w ASP.NET Core

Konwertuj widoki ASP.NET Core MVC na pliki PDF za pomocą IronPDF. Za pomocą jednej linii kodu przekształć pliki ".cshtml" w dokumenty PDF. Zintegruj tę funkcjonalność bezpośrednio ze swoją aplikacją MVC, aby płynnie generować pliki PDF z dynamicznych widoków HTML. Postępuj zgodnie z tym przewodnikiem, aby skonfigurować swoje środowisko i rozpocząć konwersję.

  1. Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf
  2. Skopiuj i uruchom ten fragment kodu.

    // using IronPdf.Extensions.Mvc.Core
    new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf");
  3. Wdrożenie do testowania w środowisku produkcyjnym

    Rozpocznij używanie IronPDF w swoim projekcie już dziś z darmową wersją próbną

    arrow pointer

ASP.NET Core Web App MVC (Model-View-Controller) to framework aplikacji internetowych dostarczany przez firmę Microsoft do tworzenia aplikacji internetowych przy użyciu .NET Core.

  • Model: Reprezentuje dane i logikę biznesową, zarządza interakcjami danych, komunikuje się ze źródłami danych.
  • Widok: Prezentuje interfejs użytkownika, wyświetla dane, przekazuje informacje użytkownikom.
  • Kontroler: Obsługuje dane wprowadzane przez użytkownika, odpowiada na żądania, komunikuje się z modelem oraz koordynuje interakcje między modelem a widokiem.

IronPDF umożliwia bezpośrednie tworzenie plików PDF z poziomu widoków w projektach ASP.NET Core MVC. Dzięki temu generowanie plików PDF w ASP.NET Core MVC jest proste i obsługuje nowoczesne funkcje, w tym stylizację CSS, wykonywanie kodu JavaScript oraz niestandardowe czcionki.

Jakiego pakietu potrzebuję do rozszerzeń IronPDF?

Pakiet IronPdf.Extensions.Mvc.Core jest rozszerzeniem głównego pakietu IronPdf. Obydwa pakiety IronPdf.Extensions.Mvc.Core i IronPdf są potrzebne do renderowania widoków do dokumentów PDF w ASP.NET Core MVC. Pakiet rozszerzeń zapewnia konkretne funkcje umożliwiające integrację z systemem wstrzykiwania zależności .NET Core oraz potokiem renderowania widoków Razor.

Install-Package IronPdf.Extensions.Mvc.Core

Dlaczego potrzebuję zarówno IronPDF, jak i pakietu rozszerzeń?

Główny pakiet IronPDF zawiera podstawowy silnik renderowania plików PDF oraz podstawowe funkcje, natomiast pakiet Extensions.Mvc.Core zapewnia specjalistyczną integrację z systemem renderowania widoków ASP.NET Core MVC. Takie rozdzielenie pozwala na lepszą modułowość i gwarantuje, że uwzględnisz tylko te funkcje, które są potrzebne w danym typie projektu. Pakiet rozszerzenia zawiera interfejs IRazorViewRenderer i implementację potrzebną do konwersji widoków Razor na HTML przed generowaniem PDF.

Którą wersję pakietu NuGet należy użyć?

Zawsze używaj pasujących wersji IronPDF i IronPdf.Extensions.Mvc.Core, aby zapewnić zgodność. Najnowsze stabilne wersje i informacje o kompatybilności wersji znajdziesz w dokumentacji pakietów NuGet. Podczas aktualizacji należy upewnić się, że oba pakiety są aktualizowane razem, aby zachować prawidłowe działanie.

Jakie są typowe problemy związane z instalacją?

Typowe problemy z instalacją obejmują niezgodności wersji między pakietami podstawowymi a rozszerzeniami, brakujące zależności lub wymagania specyficzne dla platformy. W razie problemów upewnij się, że projekt jest przeznaczony dla obsługiwanej wersji .NET, i zapoznaj się z przeglądem instalacji, aby uzyskać informacje na temat rozwiązywania problemów.

Biblioteka C# NuGet dla plików PDF

Zainstaluj za pomocą NuGet

Install-Package IronPdf.Extensions.Mvc.Core

Jak renderować widoki do plików PDF?

Potrzebujesz projektu aplikacji internetowej ASP.NET Core (Model-View-Controller), aby konwertować widoki na pliki PDF. Proces obejmuje utworzenie akcji kontrolera, która używa metody RenderRazorViewToPdf IronPDF do przekształcenia widoków Razor w dokumenty PDF. Takie podejście pozwala w pełni wykorzystać możliwości składni Razor, umożliwiając tworzenie złożonych, opartych na danych plików PDF z dynamiczną treścią.

Jakiego typu projekt powinienem użyć?

Aby uzyskać optymalną kompatybilność z funkcjami renderowania widoku IronPDF, należy użyć szablonu aplikacji internetowej ASP.NET Core (Model-View-Controller). Ten typ projektu zapewnia infrastrukturę niezbędną do renderowania widoków, w tym silnik widoków Razor i odpowiednie routowanie. W przypadku istniejących projektów należy upewnić się, że są one zgodne z wzorcem MVC i mają zainstalowane wymagane funkcje renderowania widoku.

Czy mogę z tego korzystać przy minimalnym wykorzystaniu API?

Chociaż Minimal API nie obsługują wbudowanych widoków, nadal można korzystać z funkcji konwersji HTML na PDF w IronPDF. W przypadku generowania plików PDF na podstawie widoku należy zastosować tradycyjne podejście MVC lub rozważyć Razor Pages jako alternatywę.

Jak dodać klasę modelu?

  • Przejdź do folderu "Models".
  • Utwórz nowy plik klasy C# o nazwie "Person". Klasa ta będzie pełnić rolę modelu reprezentującego dane dotyczące poszczególnych osób. Użyj poniższego fragmentu kodu:
:path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-model.cs
namespace ViewToPdfMVCCoreSample.Models
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
    }
}
Namespace ViewToPdfMVCCoreSample.Models
	Public Class Person
		Public Property Id() As Integer
		Public Property Name() As String
		Public Property Title() As String
		Public Property Description() As String
	End Class
End Namespace
$vbLabelText   $csharpLabel

Dlaczego potrzebuję modelu do generowania plików PDF?

Modele dostarczają dane strukturalne, które mogą być przekazywane do widoków w celu renderowania. Takie rozdzielenie zadań gwarantuje, że logika generowania plików PDF pozostaje przejrzysta i łatwa w utrzymaniu. Model pełni rolę umowy między kontrolerem a widokiem, zapewniając bezpieczeństwo typów i umożliwiając obsługę IntelliSense w widokach Razor.

Jakie typy danych najlepiej sprawdzają się w widokach?

Do generowania plików PDF najlepiej nadają się proste typy danych i kolekcje. Można używać złożonych obiektów zagnieżdżonych, ale może to wymagać dodatkowej logiki widoku. Aby uzyskać optymalną wydajność, spłaszcz złożone struktury danych w kontrolerze przed przekazaniem ich do widoku. Jeśli modele domenowe są zbyt złożone, warto rozważyć użycie ViewModels zaprojektowanych specjalnie do generowania plików PDF.

Oto przykład bardziej złożonej struktury modelu, odpowiedniej do generowania plików PDF:

public class InvoiceViewModel
{
    public string InvoiceNumber { get; set; }
    public DateTime InvoiceDate { get; set; }
    public decimal TotalAmount { get; set; }
    public List<InvoiceLineItem> LineItems { get; set; }
    public CustomerInfo Customer { get; set; }

    // Computed property for PDF display
    public string FormattedTotal => TotalAmount.ToString("C");
}

public class InvoiceLineItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal LineTotal => Quantity * UnitPrice;
}

public class CustomerInfo
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Address { get; set; }
}
public class InvoiceViewModel
{
    public string InvoiceNumber { get; set; }
    public DateTime InvoiceDate { get; set; }
    public decimal TotalAmount { get; set; }
    public List<InvoiceLineItem> LineItems { get; set; }
    public CustomerInfo Customer { get; set; }

    // Computed property for PDF display
    public string FormattedTotal => TotalAmount.ToString("C");
}

public class InvoiceLineItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal LineTotal => Quantity * UnitPrice;
}

public class CustomerInfo
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Address { get; set; }
}
Public Class InvoiceViewModel
    Public Property InvoiceNumber As String
    Public Property InvoiceDate As DateTime
    Public Property TotalAmount As Decimal
    Public Property LineItems As List(Of InvoiceLineItem)
    Public Property Customer As CustomerInfo

    ' Computed property for PDF display
    Public ReadOnly Property FormattedTotal As String
        Get
            Return TotalAmount.ToString("C")
        End Get
    End Property
End Class

Public Class InvoiceLineItem
    Public Property Description As String
    Public Property Quantity As Integer
    Public Property UnitPrice As Decimal
    Public ReadOnly Property LineTotal As Decimal
        Get
            Return Quantity * UnitPrice
        End Get
    End Property
End Class

Public Class CustomerInfo
    Public Property Name As String
    Public Property Email As String
    Public Property Address As String
End Class
$vbLabelText   $csharpLabel

Jak edytować kontroler?

Przejdź do folderu 'Controllers' i otwórz plik 'HomeController'. Zmienimy tylko HomeController i dodamy akcję Persons. Wskazówki można znaleźć w poniższym kodzie:

Kod poniżej najpierw tworzy instancję klasy ChromePdfRenderer, przekazując IRazorViewRenderer, ścieżkę do naszego Views/Home/Persons.cshtml oraz Listę zawierającą wymagane dane do metody RenderRazorViewToPdf. Użytkownicy mogą korzystać z RenderingOptions, aby uzyskać dostęp do szeregu funkcji, takich jak dodawanie niestandardowego tekstu, w tym nagłówków i stopki HTML w wyniku PDF, definiowanie niestandardowych marginesów oraz stosowanie numeracji stron. Aby uzyskać więcej informacji na temat zaawansowanych opcji renderowania, zapoznaj się z dokumentacją dotyczącą opcji renderowania.

Zwróć uwagęDokument PDF może być przeglądany w przeglądarce za pomocą następującego kodu: File(pdf.BinaryData, "application/pdf"). Jednak pobranie pliku PDF po wyświetleniu go w przeglądarce powoduje uszkodzenie dokumentu PDF.

using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;

namespace ViewToPdfMVCCoreSample.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IRazorViewRenderer _viewRenderService;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _viewRenderService = viewRenderService;
            _httpContextAccessor = httpContextAccessor;
        }

        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Persons()
        {
            // Example list of persons
            var persons = new List<Person>
            {
                new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
                new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
                new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
            };

            // Check if the request method is POST
            if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
            {
                // Create a new PDF renderer
                ChromePdfRenderer renderer = new ChromePdfRenderer();

                // Configure rendering options for better output
                renderer.RenderingOptions.MarginTop = 40;
                renderer.RenderingOptions.MarginBottom = 40;
                renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                renderer.RenderingOptions.Title = "Persons Report";

                // Render View to PDF document
                PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);

                Response.Headers.Add("Content-Disposition", "inline");

                // Output PDF document
                return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
            }

            return View(persons);
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;

namespace ViewToPdfMVCCoreSample.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IRazorViewRenderer _viewRenderService;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _viewRenderService = viewRenderService;
            _httpContextAccessor = httpContextAccessor;
        }

        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Persons()
        {
            // Example list of persons
            var persons = new List<Person>
            {
                new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
                new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
                new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
            };

            // Check if the request method is POST
            if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
            {
                // Create a new PDF renderer
                ChromePdfRenderer renderer = new ChromePdfRenderer();

                // Configure rendering options for better output
                renderer.RenderingOptions.MarginTop = 40;
                renderer.RenderingOptions.MarginBottom = 40;
                renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                renderer.RenderingOptions.Title = "Persons Report";

                // Render View to PDF document
                PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);

                Response.Headers.Add("Content-Disposition", "inline");

                // Output PDF document
                return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
            }

            return View(persons);
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc
Imports System.Diagnostics
Imports ViewToPdfMVCCoreSample.Models

Namespace ViewToPdfMVCCoreSample.Controllers
    Public Class HomeController
        Inherits Controller

        Private ReadOnly _logger As ILogger(Of HomeController)
        Private ReadOnly _viewRenderService As IRazorViewRenderer
        Private ReadOnly _httpContextAccessor As IHttpContextAccessor

        Public Sub New(logger As ILogger(Of HomeController), viewRenderService As IRazorViewRenderer, httpContextAccessor As IHttpContextAccessor)
            _logger = logger
            _viewRenderService = viewRenderService
            _httpContextAccessor = httpContextAccessor
        End Sub

        Public Function Index() As IActionResult
            Return View()
        End Function

        Public Async Function Persons() As Task(Of IActionResult)
            ' Example list of persons
            Dim persons = New List(Of Person) From {
                New Person With {.Name = "Alice", .Title = "Mrs.", .Description = "Software Engineer"},
                New Person With {.Name = "Bob", .Title = "Mr.", .Description = "Software Engineer"},
                New Person With {.Name = "Charlie", .Title = "Mr.", .Description = "Software Engineer"}
            }

            ' Check if the request method is POST
            If _httpContextAccessor.HttpContext.Request.Method = HttpMethod.Post.Method Then
                ' Create a new PDF renderer
                Dim renderer As New ChromePdfRenderer()

                ' Configure rendering options for better output
                renderer.RenderingOptions.MarginTop = 40
                renderer.RenderingOptions.MarginBottom = 40
                renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
                renderer.RenderingOptions.Title = "Persons Report"

                ' Render View to PDF document
                Dim pdf As PdfDocument = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons)

                Response.Headers.Add("Content-Disposition", "inline")

                ' Output PDF document
                Return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf")
            End If

            Return View(persons)
        End Function

        Public Function Privacy() As IActionResult
            Return View()
        End Function

        <ResponseCache(Duration:=0, Location:=ResponseCacheLocation.None, NoStore:=True)>
        Public Function Error() As IActionResult
            Return View(New ErrorViewModel With {.RequestId = If(Activity.Current?.Id, HttpContext.TraceIdentifier)})
        End Function
    End Class
End Namespace
$vbLabelText   $csharpLabel

Po użyciu metody RenderRazorViewToPdf otrzymujesz obiekt PdfDocument, który jest otwarty na dalsze ulepszenia i modyfikacje. Możesz przekonwertować plik PDF do formatów PDF/A lub PDF/UA, dodać swój podpis cyfrowy do wygenerowanego pliku PDF lub łączyć i dzielić dokumenty PDF w razie potrzeby. Dodatkowo biblioteka umożliwia obracanie stron, wstawianie adnotacji lub zakładek oraz nanoszenie unikalnych znaków wodnych na pliki PDF.

Czym jest usługa IRazorViewRenderer?

IRazorViewRenderer jest interfejsem usługowym zapewnionym przez pakiet IronPdf.Extensions.Mvc.Core, który obsługuje konwersję widoków Razor na HTML. Integruje się z silnikiem widoków ASP.NET Core w celu przetwarzania plików .cshtml wraz z powiązanymi modelami, wykonując całą składnię Razor i generując ostateczny kod HTML, który IronPDF konwertuje do formatu PDF.

Dlaczego warto sprawdzić metodę POST przed renderowaniem?

Sprawdzanie POST gwarantuje, że plik PDF zostanie wygenerowany tylko wtedy, gdy zostanie to wyraźnie zlecone poprzez przesłanie formularza. Zapobiega to przypadkowemu generowaniu plików PDF podczas ładowania stron i pozwala, aby ta sama akcja obsługiwała zarówno widok HTML (przy GET), jak i pobieranie pliku PDF (przy POST). Ten wzorzec jest zgodny z zasadami RESTful i zapewnia lepsze wrażenia użytkownika.

Jak mogę dostosować plik PDF?

IronPDF oferuje szerokie możliwości dostosowywania poprzez właściwość RenderingOptions. Oto przykład z bardziej zaawansowanymi ustawieniami:

// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();

// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;

// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
    Height = 25,
    HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};

// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
    RenderDelay = 500, // Wait 500ms for JS execution
    NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};

// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
    DrawDividerLine = true,
    CenterText = "CONFIDENTIAL",
    Font = new FontTypes() { FontSize = 16 }
};
// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();

// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;

// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
    Height = 25,
    HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};

// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
    RenderDelay = 500, // Wait 500ms for JS execution
    NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};

// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
    DrawDividerLine = true,
    CenterText = "CONFIDENTIAL",
    Font = new FontTypes() { FontSize = 16 }
};
' Advanced rendering configuration example
Dim renderer As New ChromePdfRenderer()

' Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20

' Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter() With {
    .Height = 25,
    .HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
}

' JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = New WaitFor() With {
    .RenderDelay = 500, ' Wait 500ms for JS execution
    .NetworkIdle = NetworkIdleTypes.NetworkIdle0 ' Wait for network requests
}

' Apply watermark
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
    .DrawDividerLine = True,
    .CenterText = "CONFIDENTIAL",
    .Font = New FontTypes() With {.FontSize = 16}
}
$vbLabelText   $csharpLabel

Jakie są typowe błędy kontrolera?

Typowe błędy to wyjątki odwołania do wartości null, gdy usługi nie są poprawnie wstrzykiwane, problemy ze ścieżkami podczas określania lokalizacji widoków oraz problemy z powiązaniem modeli. Upewnij się, że wszystkie wymagane usługi są zarejestrowane w Program.cs i używaj ścieżek względnych od katalogu głównego projektu przy określaniu lokalizacji widoków. W celu rozwiązywania problemów należy włączyć szczegółowe komunikaty o błędach w trybie programowania.

Jak dodać widok?

  • Kliknij prawym przyciskiem myszy na nowo dodaną akcję Person i wybierz 'Add View'.

Menu kontekstowe Visual Studio pokazuje opcję 'Add View...' podświetloną po kliknięciu prawym przyciskiem myszy na metodzie Persons()

  • Wybierz "Razor View" dla nowego elementu szkieletowego.

Dialog dodania widoku Razor w Visual Studio pokazujący wybór szablonu Lista i klasy modelu Person z opcjami układu

  • Wybierz szablon 'List' i klasę modelu Person.

Dialog dodania widoku Razor w Visual Studio pokazujący wybór szablonu Lista i klasy modelu Person z opcjami układu

To tworzy plik .cshtml o nazwie Persons.

  • Przejdź do folderu 'Views' -> folderu 'Home' -> plik Persons.cshtml.

Aby dodać przycisk wywołujący akcję Persons, użyj poniższego kodu:

@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
    <input type="submit" value="Print Person" />
}
@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
    <input type="submit" value="Print Person" />
}
HTML

Dlaczego warto używać FormMethod.Post do generowania plików PDF?

Używanie POST do generowania PDF przestrzega najlepszych praktyk sieciowych, czyniąc akcję eksplicytą i zapobiegając niechcianemu generowaniu PDF przy odświeżeniu przeglądarki lub zakładkach URL. Żądania GET powinny być idempotentne (nie zmieniać stanu serwera), podczas gdy żądania POST wskazują na akcję przynoszącą rezultat - w tym przypadku generowanie dokumentu PDF.

Jak mogę stylizować przycisk drukowania w pliku PDF?

Zastosuj styl przycisku PRINT za pomocą klas CSS i ulepsz go za pomocą JavaScript, aby zapewnić użytkownikom lepsze wrażenia. Oto ulepszona wersja:

@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
    <button type="submit" class="btn btn-primary pdf-download-btn">
        <i class="fas fa-file-pdf"></i> Download as PDF
    </button>
}

<style>
    .pdf-download-btn {
        background-color: #dc3545;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }

    .pdf-download-btn:hover {
        background-color: #c82333;
    }

    .pdf-download-btn:active {
        transform: translateY(1px);
    }
</style>

<script>
    // Optional: Show loading indicator during PDF generation
    document.querySelector('.pdf-form').addEventListener('submit', function() {
        const button = this.querySelector('button');
        button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
        button.disabled = true;
    });
</script>
@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
    <button type="submit" class="btn btn-primary pdf-download-btn">
        <i class="fas fa-file-pdf"></i> Download as PDF
    </button>
}

<style>
    .pdf-download-btn {
        background-color: #dc3545;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }

    .pdf-download-btn:hover {
        background-color: #c82333;
    }

    .pdf-download-btn:active {
        transform: translateY(1px);
    }
</style>

<script>
    // Optional: Show loading indicator during PDF generation
    document.querySelector('.pdf-form').addEventListener('submit', function() {
        const button = this.querySelector('button');
        button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
        button.disabled = true;
    });
</script>
HTML

Jakie szablony widoku najlepiej sprawdzają się w przypadku plików PDF?

Szablony List i Details szczególnie dobrze sprawdzają się do generowania PDF, ponieważ dostarczają ustrukturyzowane układy. Najlepsze wyniki często dają niestandardowe szablony zaprojektowane specjalnie do generowania plików PDF. Rozważ utworzenie dedykowanych widoków PDF, które są zoptymalizowane pod kątem układu wydruku, a nie wyświetlania na ekranie, usuwając elementy nawigacyjne i skupiając się na prezentacji treści.

Jak dodać sekcję do górnego paska nawigacyjnego?

  • W tym samym folderze 'Views' przejdź do folderu 'Shared' -> _Layout.cshtml. Umieść element nawigacyjny Person po Home.

Upewnij się, że wartość atrybutu asp-action dokładnie odpowiada naszej nazwie pliku, która w tym przypadku to Persons.

<header>
    <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
        <div class="container-fluid">
            <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                <ul class="navbar-nav flex-grow-1">
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</header>
<header>
    <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
        <div class="container-fluid">
            <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                <ul class="navbar-nav flex-grow-1">
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</header>
HTML

Dlaczego akcja asp musi być dokładnie dopasowana?

Atrybut asp-action używa pomocników znaczników ASP.NET Core do generowania poprawnego URL na podstawie konfiguracji tras. Dokładne dopasowanie gwarantuje, że link przekierowuje do właściwej akcji kontrolera. Niezgodności powodują błędy 404 lub przekierowanie do niezamierzonych działań. System tag helperów rozróżnia wielkość liter i musi dokładnie odpowiadać nazwie metody w kontrolerze.

Co się stanie, jeśli linki nawigacyjne nie będą pasować?

Gdy linki nawigacyjne nie odpowiadają akcjom kontrolera, użytkownicy napotykają błędy 404 lub są przekierowywani na nieprawidłowe strony. Podczas tworzenia aplikacji strona wyjątków programistycznych ASP.NET Core wyświetla szczegółowe błędy routingu. W środowisku produkcyjnym użytkownicy widzą ogólne strony błędów. Zawsze sprawdzaj, czy linki nawigacyjne dokładnie odpowiadają nazwom akcji kontrolera, aby uniknąć problemów z obsługą strony.

Jak edytować plik Program.cs?

Zarejestruj interfejsy IHttpContextAccessor i IRazorViewRenderer do kontenera iniekcji zależności (DI). Sprawdź poniższy kod w celach informacyjnych.

using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();

// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();

// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc.ViewFeatures

Dim builder = WebApplication.CreateBuilder(args)

' Add services to the container.
builder.Services.AddControllersWithViews()

builder.Services.AddSingleton(Of IHttpContextAccessor, HttpContextAccessor)()
builder.Services.AddSingleton(Of ITempDataProvider, CookieTempDataProvider)()

' Register IRazorViewRenderer here
builder.Services.AddSingleton(Of IRazorViewRenderer, RazorViewRenderer)()

' Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"

Dim app = builder.Build()

' Configure the HTTP request pipeline.
If Not app.Environment.IsDevelopment() Then
    app.UseExceptionHandler("/Home/Error")
    ' The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts()
End If

app.UseHttpsRedirection()
app.UseStaticFiles()

app.UseRouting()

app.UseAuthorization()

app.MapControllerRoute(
    name:="default",
    pattern:="{controller=Home}/{action=Index}/{id?}")

app.Run()
$vbLabelText   $csharpLabel

Dlaczego warto rejestrować usługi jako singletony?

Usługi singleton są tworzone raz i ponownie używane przez cały czas życia aplikacji, dzięki czemu są wydajne dla usług bezstanowych, takich jak IRazorViewRenderer. Ten wzorzec zmniejsza obciążenie pamięci i poprawia wydajność, ponieważ usługa renderowania widoku nie utrzymuje stanu specyficznego dla żądania. IHttpContextAccessor musi być singleton, aby był dostępny w różnych okresach życia usług.

Do czego służy ITempDataProvider?

ITempDataProvider umożliwia tymczasowe przechowywanie danych między żądaniami, często używane do wyświetlania komunikatów po przekierowaniach. W kontekście generowania PDF zapewnia, że stan widoku jest odpowiednio zachowany przy renderowaniu widoków na PDF. CookieTempDataProvider przechowuje te tymczasowe dane w zaszyfrowanych plikach cookie, zapewniając bezpieczny mechanizm zarządzania stanem.

Czy mogę używać usług zasięgu zamiast tego?

Chociaż można używać usług zasięgu w niektórych scenariuszach, IRazorViewRenderer działa najlepiej jako singleton, ponieważ nie przechowuje stanu specyficznego dla żądania. Używanie usług zasięgu powodowałoby tworzenie nowych instancji dla każdego żądania, zwiększając zużycie pamięci bez korzyści. Jednak jeśli potrzebujesz wstrzykiwać usługi zasięgu do swoich widoków, zapewnij odpowiednie zarządzanie czasem życia usług, aby uniknąć błędów w trakcie działania.

Uruchom projekt

To pokazuje, jak uruchomić projekt i wygenerować dokument PDF. Kiedy uruchomisz aplikację, przejdź do strony Persons korzystając z górnego menu nawigacyjnego, a następnie kliknij przycisk Print Person, aby wygenerować i pobrać PDF.

Visual Studio showing HomeController.cs with ASP.NET Core MVC controller code and IntelliSense assistance

Skąd mogę pobrać projekt ASP.NET Core MVC?

Pobierz kompletny kod dla tego przewodnika. Jest dostarczony jako plik zip, który można otworzyć w Visual Studio jako projekt ASP.NET Core Web App (Model-View-Controller).

Pobierz przykładowy projekt ASP.NET Core MVC

Co zawiera przykładowy projekt?

Przykładowy projekt zawiera w pełni skonfigurowaną aplikację ASP.NET Core MVC z integracją IronPDF, demonstrując przekształcanie widoków na PDF. Zawiera model Person, HomeController z logiką generowania PDF, widok Persons z poprawną składnią Razor oraz wszystkie niezbędne rejestracje usług w Program.cs. Projekt zawiera również przykładowe style i konfiguracje układu zoptymalizowane dla wyników PDF.

Jaką wersję Visual Studio powinienem używać?

Visual Studio 2022 (wersja 17.0 lub późniejsza) jest zalecana dla najlepszych wrażeń z projektami .NET 6+. Visual Studio Code z rozszerzeniami C# również dobrze sprawdza się w rozwoju międzyplatformowym. Upewnij się, że masz zainstalowany pakiet pracy ASP.NET i web development. Projekt domyślnie celuje w .NET 6.0, ale może być zaktualizowany do nowszych wersji.

Jak rozwiązywać problemy z konfiguracją projektu?

Typowe problemy z konfiguracją obejmują brakujące pakiety NuGet, nieprawidłowe wersje SDK .NET lub problemy z konfiguracją. Najpierw przywróć pakiety NuGet przy użyciu dotnet restore lub poprzez Menedżera Pakietów Visual Studio. Upewnij się, że twoja wersja .NET SDK pasuje do wymagań projektu, używając dotnet --version. W kwestii problemów licencyjnych, zobacz dokumentację kluczy licencyjnych. Jeśli wystąpią problemy z renderowaniem, sprawdź przewodnik rozwiązywania problemów dla rozwiązań.

Gotowy, aby sprawdzić, co jeszcze możesz zrobić? Sprawdź naszą stronę z samouczkami tutaj: Konwersja PDF-ów

Często Zadawane Pytania

Jaki jest najprostszy sposób konwersji widoków CSHTML do formatu PDF w ASP.NET Core MVC?

Najłatwiejszym sposobem jest użycie metody RenderRazorViewToPdf biblioteki IronPDF, która pozwala przekonwertować pliki .cshtml na dokumenty PDF za pomocą zaledwie jednej linii kodu. Wystarczy wywołać: new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf");

Jakie pakiety NuGet są potrzebne do konwersji widoków do formatu PDF w ASP.NET Core MVC?

Potrzebne są dwa pakiety: IronPdf (pakiet główny) oraz IronPdf.Extensions.Mvc.Core (pakiet rozszerzeń). Pakiet rozszerzeń zapewnia konkretne funkcje umożliwiające integrację z systemem wstrzykiwania zależności ASP.NET Core oraz potokiem renderowania widoków Razor.

Czy podczas konwersji CSHTML do formatu PDF mogę zastosować style CSS i JavaScript?

Tak, IronPDF w pełni obsługuje style CSS, wykonywanie kodu JavaScript oraz czcionki niestandardowe podczas renderowania widoków do formatu PDF. Dzięki temu pliki PDF zachowują ten sam wygląd i funkcjonalność co widoki internetowe, w tym responsywne style CSS i dynamiczną zawartość JavaScript.

Jakie są główne kroki wdrożenia konwersji View do PDF w moim projekcie ASP.NET Core MVC?

Proces składa się z 5 kroków: 1) Pobierz IronPDF i jego rozszerzenie MVC Core, 2) Dodaj klasę modelu dla swoich danych, 3) Edytuj kontroler, aby używał metody RenderRazorViewToPdf, 4) Utwórz lub zmodyfikuj widok (plik .cshtml) do renderowania PDF oraz 5) Uruchom aplikację, aby wygenerować pliki PDF.

Jak działa wzorzec MVC w przypadku generowania plików PDF z widoków?

W ASP.NET Core MVC model zawiera dane i logikę biznesową, widok (plik .cshtml) przedstawia interfejs użytkownika i wyświetla dane, a kontroler obsługuje żądania i wykorzystuje metodę RenderRazorViewToPdf biblioteki IronPDF do koordynowania generowania pliku PDF z poziomu widoku.

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
Sprawdzone przez
Jeff Fritz
Jeffrey T. Fritz
Główny Menedżer Programu - Zespół .NET Community
Jeff jest również Głównym Menedżerem Programu dla zespołów .NET i Visual Studio. Jest producentem wykonawczym wirtualnej serii konferencji .NET Conf i prowadzi 'Fritz and Friends', transmisję na żywo dla deweloperów emitowaną dwa razy w tygodniu, gdzie rozmawia o technologii i pisze kod razem z widzami. Jeff pisze warsztaty, prezentacje i planuje treści dla największych wydarzeń Microsoft dla deweloperów, w tym Microsoft Build, Microsoft Ignite, .NET Conf i Microsoft MVP Summit.
Gotowy, aby rozpocząć?
Nuget Pliki do pobrania 18,135,201 | Wersja: 2026.4 just released
Still Scrolling Icon

Wciąż przewijasz?

Czy chcesz szybko dowodu? PM > Install-Package IronPdf
Uruchom przykład i zobacz, jak Twój kod HTML zamienia się w plik PDF.