Przejdź do treści stopki
KORZYSTANIE Z IRONPDF

Jak zbudować scentralizowaną usługę generowania plików PDF przy użyciu ASP.NET Core i IronPDF

Zbuduj gotowe do produkcji API PDF .NET za pomocą ASP.NET Core i IronPDF, aby scentralizować logikę generowania PDF, umożliwiając spójną tworzenie dokumentów w aplikacjach z użyciem punktów końcowych RESTful do konwersji HTML na PDF, scalania, dodawania znaków wodnych i przetwarzania szablonów dynamicznych.

Pracując z nowoczesnymi aplikacjami, deweloperzy .NET często muszą zbudować scentralizowaną usługę generowania PDF. Niezależnie od tego, czy generujesz faktury, raporty, certyfikaty, czy umowy, posiadanie dedykowanego API PDF .NET poprawia przepływ pracy związany z generowaniem PDF. Jak to pomaga? Zapewnia spójność, łatwość utrzymania i skalowalność w aplikacjach desktopowych i internetowych. Zarządzanie treścią dokumentów, stronami PDF i polami formularzy PDF staje się proste.

W tym samouczku dowiesz się, jak zbudować gotowe do produkcji API PDF za pomocą ASP.NET Core i IronPDF, potężnej biblioteki PDF .NET. Utworzymy punkty końcowe RESTful, które generują PDF z HTML, scalają dokumenty, dodają znaki wodne i obsługują różne scenariusze PDF w twoim Web API.

Dlaczego warto zbudować dedykowane API PDF?

Diagram architektury pokazujący aplikacje klienta (webowe, desktopowe, mobilne), które wysyłają treści HTML, URL, lub dynamiczne dane do warstwy Controlera/Serwisu API PDF, która generuje dokumenty PDF.

Zanim zagłębimy się w kod, zastanówmy się, dlaczego tworzenie dedykowanego API PDF ma sens:

  • Scentralizowana logika: Cała logika generowania PDF znajduje się w jednym miejscu, upraszczając utrzymanie i aktualizacje.
  • Architektura mikroserwisów: Idealne dla architektur zorientowanych na usługi, gdzie różne aplikacje potrzebują funkcji PDF.
  • Optymalizacja wydajności: Łatwiej skalować i optymalizować dedykowaną usługę dla dużych PDF, wielu stron i dynamicznych danych używając operacji asynchronicznych i technik wydajności.
  • Neutralność językowa: Każda aplikacja kliencka może używać API niezależnie od języka programowania.
  • Spójny wynik: Zapewnia, że wszystkie PDF w twojej organizacji mają spójny układ, formatowanie i treść.

Czy jesteś gotowy do rozpoczęcia budowy? Pobierz bezpłatną wersję próbną IronPDF i postępuj zgodnie z tym samouczkiem, aby programowo tworzyć pliki PDF w swoich projektach .NET Framework.

Co czyni IronPDF kompletną biblioteką PDF .NET?

Strona główna IronPDF dla .NET pokazująca przykłady kodu C# do konwersji HTML na PDF z funkcjami takimi jak renderowanie HTML, zapis plików i komenda instalacji NuGet

IronPDF wyróżnia się jako wiodąca biblioteka PDF dla deweloperów .NET, oferując kompleksowy zestaw funkcji, które sprawiają, że generowanie PDF w projektach Web API jest proste i niezawodne. Oparta na silniku renderującym Chrome, zapewnia konwersje HTML na PDF z zachowaniem pikseli w kilku liniach kodu, jednocześnie zachowując wszystkie style, wykonania JavaScript i responsywne układy.

Kluczowe możliwości, które czynią IronPDF idealnym wyborem dla rozwoju PDF API .NET:

Jak skonfigurować projekt API dokumentów PDF?

Zacznijmy od stworzenia nowego projektu ASP.NET Core Web API i zainstalowania niezbędnych pakietów.

Jakie są wymagania wstępne?

  • .NET 6.0 SDK lub nowszy
  • Visual Studio 2022 lub Visual Studio Code
  • Postman lub podobne narzędzie do testowania API do testowania twojego API PDF REST

Jak utworzyć projekt?

Najpierw, utwórzmy projekt, w którym zbudujemy nasze narzędzie do generowania PDF.

dotnet new webapi -n PdfApiService
cd PdfApiService
dotnet new webapi -n PdfApiService
cd PdfApiService
SHELL

Jak zainstalować IronPDF?

Następnie, dodaj IronPDF do swojego projektu za pomocą NuGet:

dotnet add package IronPDF
dotnet add package IronPDF
SHELL

Lub, używając Konsoli Menedżera Pakietów NuGet w Visual Studio:

Install-Package IronPDF

Dla zaawansowanych opcji instalacji, w tym pakietów specyficznych dla platformy, konfiguracji Dockera lub konfiguracji Linuxa, zobacz dokumentację instalacyjną IronPDF.

Jaką strukturę projektu powinienem zastosować?

Dobra praktyka programowania w C# wymaga utrzymania czystego i dobrze zorganizowanego folderu projektu. Na przykład:

Solution Explorer w Visual Studio pokazujący strukturę folderów projektu .NET PDF API Service z katalogami Controllers, Models i Services

Jak stworzyć swoje pierwsze odniesienie PDF?

Zbudujmy prosty punkt końcowy, który konwertuje HTML na format PDF. Najpierw stwórzmy interfejs usługi i implementację:

Jak utworzyć serwis PDF?

Najpierw, dodaj następujące do pliku IPdfService.cs:

public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
Public Interface IPdfService
    Function GeneratePdfFromHtml(htmlContent As String) As Byte()
    Function GeneratePdfFromUrl(url As String) As Byte()
End Interface
$vbLabelText   $csharpLabel

W pliku PdfService.cs, dodaj to:

using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
Imports IronPdf

Public Class PdfService
    Implements IPdfService

    Private ReadOnly _renderer As ChromePdfRenderer

    Public Sub New()
        _renderer = New ChromePdfRenderer()
        ' Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20
        _renderer.RenderingOptions.MarginBottom = 20
        _renderer.RenderingOptions.PrintHtmlBackgrounds = True
    End Sub

    Public Function GeneratePdfFromHtml(htmlContent As String) As Byte()
        ' Generate PDF from HTML using the .NET PDF API
        Dim pdf = _renderer.RenderHtmlAsPdf(htmlContent)
        Return pdf.BinaryData
    End Function

    Public Function GeneratePdfFromUrl(url As String) As Byte()
        ' Convert URL to PDF in the REST API
        Dim pdf = _renderer.RenderUrlAsPdf(url)
        Return pdf.BinaryData
    End Function

End Class
$vbLabelText   $csharpLabel

Plik PdfService zajmuje się konwersją HTML na PDF. Używając ChromePdfRenderer IronPDF, ta klasa konfiguruje domyślne ustawienia jak marginesy stron i renderowanie tła dla profesjonalnych wyników. Dla zaawansowanych konfiguracji renderowania, zapoznaj się z opcje renderowania IronPDF.

Kiedy kontroler przekazuje surowe HTML, serwis renderuje to do wysokiej jakości PDF i zwraca dane bajtowe do pobrania. Przekształca również całe strony internetowe bezpośrednio do PDF przy użyciu konwersji URL na PDF.

Jak utworzyć kontroler?

Teraz utwórz kontroler dla swojego API. To zapewnia punkt końcowy, który generuje pliki PDF z HTML i pozwala pobierać i zapisywać dokumenty PDF na swoim systemie.

// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
Imports Microsoft.AspNetCore.Mvc

<ApiController>
<Route("api/[controller]")>
Public Class PdfController
    Inherits ControllerBase

    Private ReadOnly _pdfService As IPdfService

    Public Sub New(pdfService As IPdfService)
        _pdfService = pdfService
    End Sub

    <HttpPost("html-to-pdf")>
    Public Function ConvertHtmlToPdf(<FromBody> request As HtmlRequest) As IActionResult
        Try
            Dim pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent)
            ' Return as downloadable file
            Return File(pdfBytes, "application/pdf", "document.pdf")
        Catch ex As Exception
            Return BadRequest($"Error generating PDF: {ex.Message}")
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

Następnie, w pliku HtmlRequest.cs, dodaj to:

// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
' Models/HtmlRequest.vb
Public Class HtmlRequest
    Public Property HtmlContent As String
    Public Property FileName As String = "document.pdf"
End Class
$vbLabelText   $csharpLabel

To ustawia punkt końcowy API, który konwertuje HTML na PDF do pobrania. Kiedy ktoś wysyła HTML do api/pdf/html-to-pdf, PdfController deleguje konwersję do serwisu.

Po utworzeniu, kontroler zwraca PDF jako plik do pobrania. Żądanie używa modelu HtmlRequest, zawierającego HTML i opcjonalną nazwę pliku. To ułatwia klientom przesyłanie HTML i odbieranie dopracowanego PDF.

Jak zarejestrować serwisy?

Zaktualizuj swój Program.cs, aby zarejestrować serwis PDF:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
Imports Microsoft.AspNetCore.Builder
Imports Microsoft.Extensions.DependencyInjection

Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllers()
builder.Services.AddEndpointsApiExplorer()
builder.Services.AddSwaggerGen()
' Register PDF service
builder.Services.AddSingleton(Of IPdfService, PdfService)()
Dim app = builder.Build()
If app.Environment.IsDevelopment() Then
    app.UseSwagger()
    app.UseSwaggerUI()
End If
app.UseHttpsRedirection()
app.MapControllers()
app.Run()
$vbLabelText   $csharpLabel

Jak obsłużyć różne typy odpowiedzi?

Twoje API powinno obsługiwać różne sposoby zwracania PDF w zależności od potrzeb klienta:

[HttpPost("generate")]
public IActionResult GeneratePdf([FromBody] PdfRequest request)
{
    var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
    switch (request.ResponseType?.ToLower())
    {
        case "base64":
            return Ok(new
            {
                data = Convert.ToBase64String(pdfBytes),
                filename = request.FileName
            });
        case "inline":
            return File(pdfBytes, "application/pdf");
        default: // download
            return File(pdfBytes, "application/pdf", request.FileName);
    }
}
[HttpPost("generate")]
public IActionResult GeneratePdf([FromBody] PdfRequest request)
{
    var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
    switch (request.ResponseType?.ToLower())
    {
        case "base64":
            return Ok(new
            {
                data = Convert.ToBase64String(pdfBytes),
                filename = request.FileName
            });
        case "inline":
            return File(pdfBytes, "application/pdf");
        default: // download
            return File(pdfBytes, "application/pdf", request.FileName);
    }
}
Imports Microsoft.AspNetCore.Mvc

<HttpPost("generate")>
Public Function GeneratePdf(<FromBody> request As PdfRequest) As IActionResult
    Dim pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent)
    Select Case request.ResponseType?.ToLower()
        Case "base64"
            Return Ok(New With {
                .data = Convert.ToBase64String(pdfBytes),
                .filename = request.FileName
            })
        Case "inline"
            Return File(pdfBytes, "application/pdf")
        Case Else ' download
            Return File(pdfBytes, "application/pdf", request.FileName)
    End Select
End Function
$vbLabelText   $csharpLabel

To dodaje elastyczny punkt końcowy generowania PDF. Zamiast wymuszać pobierania, metoda GeneratePdf pozwala klientom wybrać, jak otrzymają wyniki: jako pobranie, inline w przeglądarce lub zakodowane w Base64 dla użycia w API.

Model PdfRequest rozbudowuje HtmlRequest opcją ResponseType. To daje użytkownikom kontrolę nad dostarczaniem PDF, czyniąc API bardziej wszechstronnym. Dla obsługi PDF w pamięci bez dostępu do systemu plików, zobacz dokumentację strumieni pamięci IronPDF.

Kiedy uruchomimy nasz program, zobaczymy ten wynik na Swagger:

Dokumentacja Swagger UI pokazująca punkty końcowe PdfApiService z trzema metodami POST dla operacji PDF: html-to-pdf, generate i url-to-pdf, wraz z schematami żądań.

Jak zaimplementować powszechne operacje PDF?

Rozszerzmy naszą usługę o obsługę różnych scenariuszy generowania PDF:

Jak przetworzyć URL na PDF?

[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() =>
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf",
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() =>
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf",
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc

<HttpPost("url-to-pdf")>
Public Async Function ConvertUrlToPdf(<FromBody> request As UrlRequest) As Task(Of IActionResult)
    Try
        Dim pdfBytes = Await Task.Run(Function() _pdfService.GeneratePdfFromUrl(request.Url))
        Return File(pdfBytes, "application/pdf", $"{If(request.FileName, "website")}.pdf")
    Catch ex As Exception
        Return BadRequest($"Failed to convert URL: {ex.Message}")
    End Try
End Function

Public Class UrlRequest
    Public Property Url As String
    Public Property FileName As String
End Class
$vbLabelText   $csharpLabel

Ten punkt końcowy konwertuje URL na PDF do pobrania. Kiedy żądanie POST trafia do /api/pdf/url-to-pdf, kontroler używa _pdfService, aby przekonwertować URL na bajty PDF w tle, a następnie zwraca je do pobrania. Jeśli konwersja się nie powiedzie, odpowiada jasnym komunikatem o błędzie. Dla stron internetowych z autentykacją, zapoznaj się z dokumentacją logowania IronPDF.

Spróbujmy użyć URL "https://www.apple.com/nz" i przetestujmy żądanie POST. Poniżej znajduje się uzyskany wynik:

Jak wygląda wynik?

Strona główna Apple Nowa Zelandia pokazująca wiele sekcji produktów, w tym iPhone 16, MacBook Air, Apple Watch i AirPods z przyciskami 'Dowiedz się więcej' i 'Kup' - demonstracja konwersji URL na PDF

Jak dodać własne znaki wodne?

public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
Imports IronPdf

Public Function AddWatermarkFromFile(filePath As String, watermarkText As String) As Byte()
    ' Load PDF directly from file
    Dim pdf = PdfDocument.FromFile(filePath)
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    )
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

To ręcznie ładuje lokalny plik do testowania. Możesz dostosować to tak, aby twoje API PDF generowało PDF, a następnie łatwo dodawało własne znaki wodne. Dla zaawansowanych opcji dodawania znaków wodnych, w tym znaków wodnych w formie obrazów i niestandardowego pozycjonowania, zobacz przewodnik dodawania znaków wodnych.

Jak wygląda wynik z dodanym znakiem wodnym?

Zabezpieczony dokument z napisem 'POUFNE' umieszczonym ukośnie w poprzek pustej strony, z identyfikatorem dokumentu: BA811648DCE1FF2AAA55E7CE pokazanym u góry

Jak dodać dynamiczne dane za pomocą szablonów?

W przypadku aplikacji rzeczywistego świata, często będziesz musiał generować PDF-y ze szablonów z dynamicznymi danymi:

[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
Imports Microsoft.AspNetCore.Mvc

<HttpPost("from-template")>
Public Function GenerateFromTemplate(<FromBody> request As TemplateRequest) As IActionResult
    ' Simple template replacement
    Dim html As String = request.Template
    For Each item In request.Data
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value)
    Next
    Dim pdfBytes As Byte() = _pdfService.GeneratePdfFromHtml(html)
    Return File(pdfBytes, "application/pdf", request.FileName)
End Function

Public Class TemplateRequest
    Public Property Template As String
    Public Property Data As Dictionary(Of String, String)
    Public Property FileName As String = "document.pdf"
End Class
$vbLabelText   $csharpLabel

Dla zaawansowanych scenariuszy szablonów z użyciem Razor, Handlebars lub innych silników, zobacz dokumentację HTML na PDF IronPDF. Możesz również zbadać konwersję CSHTML do PDF dla aplikacji MVC i Razor do PDF dla aplikacji Blazor. Dla renderowania Razor w trybie bezgłowym, zapoznaj się z przewodnikiem CSHTML dla renderowania bezgłowego.

Jak zoptymalizować wydajność?

Podczas tworzenia API PDF do produkcji, wydajność jest kluczowa. Oto kluczowe strategie optymalizacji:

Dlaczego używać operacji asynchronicznych?

Używaj kodowania asynchronicznego, gdy projekty obejmują operacje I/O. To jest szczególnie pomocne, gdy zawartość PDF pochodzi z zewnętrznych źródeł, takich jak:

  • Pobieranie stron HTML (RenderUrlAsPdf)

    Pobieranie obrazów, CSS lub fontów przez HTTP⟩

    Odczyt/zapis plików na dysk lub do chmurowej przechowalni⟩

Te operacje mogą blokować wątki, ale async zapobiega oczekiwaniu wątków API na bezczynnie. Dla pełnych wzorców generacji PDF async, zobacz przewodnik generacji PDF async.

Przykład:

public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() =>
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() =>
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
Imports System.Threading.Tasks

Public Async Function GeneratePdfFromHtmlAsync(htmlContent As String) As Task(Of Byte())
    Return Await Task.Run(Function()
                              Dim pdf = _renderer.RenderHtmlAsPdf(htmlContent)
                              Return pdf.BinaryData
                          End Function)
End Function
$vbLabelText   $csharpLabel

Dla scenariuszy równoległej generacji PDF, eksploruj wielowątkowe i równoległe przetwarzanie technik.

Jakie opcje renderowania należy skonfigurować?

Skonfiguruj IronPDF dla optymalnej wydajności:

_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
$vbLabelText   $csharpLabel

Dla pełnych opcji konfiguracji renderowania, w tym ustawień widoku, niestandardowych rozmiarów papieru i orientacji stron, zobacz dokumentację opcji renderowania.

Jak zabezpieczyć swoje API PDF?

Bezpieczeństwo jest kluczowe dla każdego API produkcyjnego. Oto proste podejście do uwierzytelniania za pomocą klucza API:

// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
Imports Microsoft.AspNetCore.Http
Imports Microsoft.Extensions.Configuration
Imports System.Threading.Tasks

' Middleware/ApiKeyMiddleware.vb
Public Class ApiKeyMiddleware
    Private ReadOnly _next As RequestDelegate
    Private Const ApiKeyHeader As String = "X-API-Key"

    Public Sub New(next As RequestDelegate)
        _next = next
    End Sub

    Public Async Function InvokeAsync(context As HttpContext) As Task
        Dim apiKey As String = Nothing
        If Not context.Request.Headers.TryGetValue(ApiKeyHeader, apiKey) Then
            context.Response.StatusCode = 401
            Await context.Response.WriteAsync("API Key required")
            Return
        End If

        ' Validate API key (in production, check against database)
        Dim validApiKey As String = context.RequestServices.GetRequiredService(Of IConfiguration)()("ApiKey")
        If apiKey <> validApiKey Then
            context.Response.StatusCode = 403
            Await context.Response.WriteAsync("Invalid API Key")
            Return
        End If

        Await _next(context)
    End Function
End Class

' In Program.vb
app.UseMiddleware(Of ApiKeyMiddleware)()
$vbLabelText   $csharpLabel

Dla zaawansowanych scenariuszy uwierzytelniania, rozważ:

Dla zabezpieczeń specyficznych dla PDF, wdroż ochronę hasłem, podpisy cyfrowe i sanitację PDF, aby usunąć potencjalnie złośliwe treści.

Jak zbudować API generowania faktur w rzeczywistości?

Zbudujmy praktyczny punkt końcowy generowania faktur, demonstrujący pełną implementację. Ten przykład pokazuje, jak produkcyjne API PDF .NET generuje profesjonalne faktury z dynamicznymi danymi.

!{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101000101111101010011010101000100000101010010010101000100010101000100010111110101011101001001010100010010000101111101010000010100100100111101000100010101010100001101010100010111110101010001010010010010010100000101001100010111110100001001001100010011110100001101001011--}

Najpierw utwórz nowy plik w katalogu Models. Tutaj nazwałem mój plik Invoice.cs. Następnie dodaj następujący kod:

public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
Public Class Invoice
    Public Property InvoiceNumber As String
    Public Property [Date] As DateTime
    Public Property CustomerName As String
    Public Property CustomerAddress As String
    Public Property Items As List(Of InvoiceItem)
    Public Property Tax As Decimal
End Class

Public Class InvoiceItem
    Public Property Description As String
    Public Property Quantity As Integer
    Public Property UnitPrice As Decimal
    Public ReadOnly Property Total As Decimal
        Get
            Return Quantity * UnitPrice
        End Get
    End Property
End Class
$vbLabelText   $csharpLabel

Następnie utwórz nowy plik serwisowy dla generatora faktur. W folderze Services dodaj poniższy kod. Stworzyłem plik o nazwie InvoiceService.cs. Ten kod obsługuje stylizację i układ twojej faktury PDF:

public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
    {
        var html = BuildInvoiceHtml(invoice);
        // Add footer with page numbers
        _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
        {
            MaxHeight = 15,
            HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
            DrawDividerLine = true
        };
        var pdf = _renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item =>
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{
                    background-color: #f8f9fa;
                    padding: 20px;
                    margin-bottom: 20px;
                }}
                table {{
                    width: 100%;
                    border-collapse: collapse;
                }}
                th, td {{
                    padding: 10px;
                    border-bottom: 1px solid #ddd;
                }}
                th {{
                    background-color: #007bff;
                    color: white;
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{
                    margin-top: 20px;
                    text-align: right;
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
    {
        var html = BuildInvoiceHtml(invoice);
        // Add footer with page numbers
        _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
        {
            MaxHeight = 15,
            HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
            DrawDividerLine = true
        };
        var pdf = _renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item =>
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{
                    background-color: #f8f9fa;
                    padding: 20px;
                    margin-bottom: 20px;
                }}
                table {{
                    width: 100%;
                    border-collapse: collapse;
                }}
                th, td {{
                    padding: 10px;
                    border-bottom: 1px solid #ddd;
                }}
                th {{
                    background-color: #007bff;
                    color: white;
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{
                    margin-top: 20px;
                    text-align: right;
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
Imports System
Imports System.Linq

Public Class InvoiceService
    Private ReadOnly _renderer As ChromePdfRenderer

    Public Sub New()
        _renderer = New ChromePdfRenderer()
        _renderer.RenderingOptions.MarginTop = 10
        _renderer.RenderingOptions.MarginBottom = 10
        _renderer.RenderingOptions.PrintHtmlBackgrounds = True
    End Sub

    Public Function GenerateInvoice(invoice As Invoice) As Byte()
        Dim html = BuildInvoiceHtml(invoice)
        ' Add footer with page numbers
        _renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
            .MaxHeight = 15,
            .HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
            .DrawDividerLine = True
        }
        Dim pdf = _renderer.RenderHtmlAsPdf(html)
        Return pdf.BinaryData
    End Function

    Private Function BuildInvoiceHtml(invoice As Invoice) As String
        Dim subtotal = invoice.Items.Sum(Function(i) i.Total)
        Dim taxAmount = subtotal * (invoice.Tax / 100)
        Dim total = subtotal + taxAmount
        Dim itemsHtml = String.Join("", invoice.Items.Select(Function(item) _
            $"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"))
        Return $"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{
                    background-color: #f8f9fa;
                    padding: 20px;
                    margin-bottom: 20px;
                }}
                table {{
                    width: 100%;
                    border-collapse: collapse;
                }}
                th, td {{
                    padding: 10px;
                    border-bottom: 1px solid #ddd;
                }}
                th {{
                    background-color: #007bff;
                    color: white;
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{
                    margin-top: 20px;
                    text-align: right;
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>"
    End Function
End Class
$vbLabelText   $csharpLabel

Na koniec utwórz nowy kontroler, aby uzyskać dostęp i tworzyć faktury za pomocą API:

[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
Imports Microsoft.AspNetCore.Mvc

<ApiController>
<Route("api/[controller]")>
Public Class InvoiceController
    Inherits ControllerBase

    Private ReadOnly _invoiceService As InvoiceService

    Public Sub New(invoiceService As InvoiceService)
        _invoiceService = invoiceService
    End Sub

    <HttpPost("generate")>
    Public Function GenerateInvoice(<FromBody> invoice As Invoice) As IActionResult
        Try
            Dim pdfBytes = _invoiceService.GenerateInvoice(invoice)
            Dim fileName = $"Invoice_{invoice.InvoiceNumber}.pdf"
            Return File(pdfBytes, "application/pdf", fileName)
        Catch ex As Exception
            Return StatusCode(500, $"Error generating invoice: {ex.Message}")
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

Dla zaawansowanych funkcji faktur, rozważ dodanie kodów kreskowych, kodów QR, numerów stron i niestandardowych nagłówków/stopki. Możesz również wdrożyć zgodność z PDF/A do długoterminowego archiwizowania lub zintegrować z przepływami pracy z podpisami elektronicznymi.

Jak wygląda wynik generowania faktur?

PDF invoice document showing Invoice #INV-1023 dated 2025-08-22, with a single line item for 'Misc Object' totaling $495.00 including tax

Jakie są kwestie wdrożeniowe dotyczące kontenerów?

Chociaż ten samouczek koncentruje się na lokalnym rozwoju, oto krótki przegląd konteneryzacji Twojego API PDF:

Jak utworzyć podstawowy plik Dockerfile?

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["dotnet", "PdfApiService.dll"]

Dla szczegółowych przewodników wdrożeniowych Twojego API PDF .NET, zobacz:

Jakie są najlepsze praktyki obsługi błędów?

Dla programów odporne na błędy, zaimplementuj globalny obsługiwacz błędów dla spójnych odpowiedzi błędów:

// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ErrorHandlingMiddleware> _logger;
    public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path);
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = ex switch
        {
            ArgumentNullException => 400,
            UnauthorizedAccessException => 401,
            _ => 500
        };
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message,
            statusCode = context.Response.StatusCode
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ErrorHandlingMiddleware> _logger;
    public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path);
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = ex switch
        {
            ArgumentNullException => 400,
            UnauthorizedAccessException => 401,
            _ => 500
        };
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message,
            statusCode = context.Response.StatusCode
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
' Middleware/ErrorHandlingMiddleware.vb
Public Class ErrorHandlingMiddleware
    Private ReadOnly _next As RequestDelegate
    Private ReadOnly _logger As ILogger(Of ErrorHandlingMiddleware)

    Public Sub New(ByVal [next] As RequestDelegate, ByVal logger As ILogger(Of ErrorHandlingMiddleware))
        _next = [next]
        _logger = logger
    End Sub

    Public Async Function InvokeAsync(ByVal context As HttpContext) As Task
        Try
            Await _next(context)
        Catch ex As Exception
            _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path)
            Await HandleExceptionAsync(context, ex)
        End Try
    End Function

    Private Shared Async Function HandleExceptionAsync(ByVal context As HttpContext, ByVal ex As Exception) As Task
        context.Response.ContentType = "application/json"
        context.Response.StatusCode = If(TypeOf ex Is ArgumentNullException, 400, If(TypeOf ex Is UnauthorizedAccessException, 401, 500))
        Dim response = New With {
            .error = "An error occurred processing your request",
            .message = ex.Message,
            .statusCode = context.Response.StatusCode
        }
        Await context.Response.WriteAsync(JsonSerializer.Serialize(response))
    End Function
End Class
$vbLabelText   $csharpLabel

Dla specyficznych scenariuszy rozwiązywania problemów z IronPDF, zapoznaj się z:

Gotowy na zbudowanie swojego gotowego do produkcji API PDF .NET?

Zbudowałeś teraz solidne API PDF .NET używając ASP.NET Core i IronPDF, które obsługuje różne scenariusze generowania dokumentów. To REST API zapewnia solidną podstawę do scentralizowanych operacji PDF w Twoich aplikacjach.

Najważniejsze wnioski:

  • IronPDF sprawia, że generowanie PDF w projektach Web API jest proste dzięki renderowaniu opartemu na Chrome.
  • Łatwo edytuj istniejące PDF za pomocą zaawansowanych narzędzi edycyjnych IronPDF.
  • Zasady projektowania RESTful zapewniają, że twoje API PDF jest intuicyjne i łatwe w utrzymaniu.
  • Poprawna obsługa błędów i środki bezpieczeństwa są niezbędne do produkcji.
  • Optymalizacja wydajności poprzez operacje asynchroniczne i buforowanie poprawia skalowalność.
  • Pełna obsługa aplikacji desktopowych i internetowych z skalowalnymi rozwiązaniami dokumentowymi.

IronPDF pozwala deweloperom tworzyć PDF, zapisywać pliki PDF i efektywnie konwertować HTML, czyniąc go niezbędnym API PDF dla nowoczesnych aplikacji .NET Framework.

Jakie są kolejne kroki?

Gotowy do wdrożenia IronPDF w swoim produkcyjnym .NET PDF API? Oto Twoje następne kroki:

  1. Rozpocznij darmowy okres próbny - Przetestuj IronPDF z pełną funkcjonalnością w swoim środowisku deweloperskim.
  2. Poznawaj zaawansowane funkcje - Odkryj podpisy cyfrowe, formularze PDF, zgodność z PDF/A, zarządzanie metadanymi i inne zaawansowane funkcje PDF.
  3. Skaluj z pewnością - Zapoznaj się z opcje licencjonowania dla swoich potrzeb API produkcyjnego, w tym rozszerzenia i ulepszenia.

Zbuduj swoje .NET PDF API już dziś i usprawnij generowanie dokumentów w całym ekosystemie aplikacji dzięki IronPDF!

Często Zadawane Pytania

Do czego służy IronPDF w aplikacjach .NET?

IronPDF służy do generowania, edycji i konwersji plików PDF w aplikacjach .NET, dzięki czemu idealnie nadaje się do tworzenia scentralizowanych usług związanych z plikami PDF.

Jak zintegrować IronPDF z ASP.NET Core?

IronPDF można zintegrować z ASP.NET Core poprzez zainstalowanie pakietu IronPDF NuGet, co pozwala na stworzenie scentralizowanej usługi generowania plików PDF.

Jakie są kluczowe funkcje IronPDF do generowania plików PDF?

Kluczowe funkcje IronPDF obejmują konwersję HTML do PDF, łączenie i dzielenie plików PDF, dodawanie nagłówków i stopek oraz wyodrębnianie tekstu i obrazów.

Czy IronPDF radzi sobie ze złożonymi układami plików PDF?

Tak, IronPDF może obsługiwać złożone układy PDF dzięki możliwości konwersji treści HTML i CSS na dokładnie renderowane dokumenty PDF.

Czy w IronPDF można dostosować sposób tworzenia plików PDF?

Tak, IronPDF umożliwia dostosowywanie procesu tworzenia plików PDF, w tym ustawianie rozmiaru strony, marginesów oraz dodawanie znaków wodnych lub adnotacji.

Czy IronPDF obsługuje funkcje zabezpieczeń plików PDF?

IronPDF obsługuje funkcje zabezpieczeń PDF, takie jak ochrona hasłem i szyfrowanie, w celu zabezpieczenia wygenerowanych dokumentów PDF.

Jakie formaty IronPDF może konwertować do plików PDF?

IronPDF może konwertować różne formaty do plików PDF, w tym HTML, adresy URL i pliki ASPX, dzięki czemu jest wszechstronnym narzędziem do różnych zastosowań.

W jaki sposób IronPDF radzi sobie z generowaniem plików PDF na dużą skalę?

IronPDF jest zoptymalizowany pod kątem wydajności, co pozwala mu efektywnie obsługiwać zadania związane z generowaniem plików PDF na dużą skalę w aplikacjach .NET.

Czy IronPDF można używać w aplikacjach chmurowych?

Tak, IronPDF może być używany w aplikacjach opartych na chmurze, obsługując wdrażanie na platformach takich jak Azure i AWS w celu zapewnienia skalowalnych usług PDF.

Jakie wersje .NET obsługuje IronPDF?

IronPDF obsługuje wiele wersji .NET, w tym .NET Core i .NET Framework, zapewniając kompatybilność z szeroką gamą projektów.

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