Altbilgi içeriğine atla
IRONPDF KULLANARAK

C# Kullanarak ASP.NET'te PDF Nasıl Uretilir

İster fatura, rapor, sertifika veya bilet oluşturuyor olun, PDF'leri programlı olarak oluşturmak modern web uygulamaları için kritik bir gerekliliktir. Piksel mükemmelliğinde işleme ve Enterprise özelliklerine sahip sağlam PDF üretimi uygulamak isteyen bir ASP.NET Core .NET geliştiricisiyseniz doğru yerdesiniz.

Bu kapsamlı kılavuz, PDF belgelerinin kolaylıkla oluşturulmasını sağlayan güçlü bir .NET kütüphanesi olan IronPDF'yi kullanarak profesyonel PDF dosyası oluşturma konusunda size yol gösterecektir. Temel kurulumdan gelişmiş toplu işlemeye kadar her şeyi keşfedecek, ne kadar verimli ve kolay entegre edilebileceğini göstereceğiz. Sonunda, IronPDF'yi bir profesyonel gibi kullanarak ASP.NET uygulamanızda PDF belgeleri oluşturmak için güçlü bir PDF dönüştürücüsüne sahip olacaksınız.

Neden ASP.NET Core'da PDF Oluşturmalı?

Sunucu tarafı PDF oluşturma, istemci tarafı alternatiflerine göre önemli avantajlar sunar. PDF'leri sunucuda oluşturduğunuzda, tüm tarayıcılarda ve cihazlarda tutarlı çıktı elde eder, istemci tarafı kaynaklara bağımlılığı ortadan kaldırır ve hassas veriler üzerinde daha iyi kontrol sağlarsınız. HTML'den PDF'e dönüştürme için yaygın iş senaryoları şunları içerir:

  • Finansal belgeler: Faturalar, ekstreler ve işlem makbuzları
  • Uyumluluk raporları: Düzenleyici başvurular ve denetim belgeleri
  • Kullanıcı sertifikaları: Eğitim tamamlamaları ve Professional sertifikalar
  • Etkinlik biletleri: QR kodlu giriş kartları ve biniş kartları
  • Veri aktarımları: Analitik raporlar ve gösterge tablosu anlık görüntüleri

Ayrıca, sunucu tarafı yaklaşımı PDF'lerin tüm tarayıcılarda ve işletim sistemlerinde tutarlı olmasını sağlar. Bu da çevirinin yasal ve finansal belgeler açısından oldukça saygın olmasını sağlıyor.

IronPDF PDF Üretiminizi Nasıl Dönüştürüyor?

IronPDF, kaputun altında eksiksiz bir Chrome işleme motoru kullanan HTML dönüştürücüsü sayesinde .NET ekosisteminde öne çıkan bir PDF kütüphanesidir. Bu, PDF belgelerinizin modern CSS3, JavaScript yürütme ve web yazı tipleri için tam destekle Google Chrome'da olduğu gibi görüntüleneceği anlamına gelir. Diğer kütüphanelerin aksine IronPDF, mevcut HTML, CSS ve JavaScript bilgilerinizi ASP.NET Core uygulamalarınızda doğrudan PDF oluşturma yeteneklerine dönüştürmenizi sağlar.

Geliştirmenizi dönüştüren temel avantajlar:

  • Piksel mükemmelliğinde doğruluk için Chrome tabanlı işleme, HTML'den PDF'e dönüştürme görevlerini yerine getirirken tarayıcıda gördüklerinizle eşleşir (genellikle sadece birkaç satır kodla)
  • Tam HTML5, CSS3 ve JavaScript desteği, Bootstrap gibi modern çerçeveler dahil
  • harici bağımlılıklar veya komut satırı araçları olmadan Native .NET entegrasyonu
  • Çapraz platform uyumluluğu .NET 6/7/8, .NET Core ve hatta eski uygulamalar için .NET Framework 4.6.2+ desteği
  • birleştirme, watermarking ve PDF sayfalarınızın dijital imzaları dahil olmak üzere üretim sonrası manipülasyon için Kapsamlı API.

NuGet NuGet ile Yükle

PM >  Install-Package IronPdf

IronPDF üzerine NuGet için hızlı bir kurulum kontrol edin. 10 milyondan fazla indirme ile C# ile PDF geliştirmesini dönüştürüyor. DLL veya Windows yükleyicisini de indirebilirsiniz.

Setting Up Your ASP.NET Core Project

PDF üretimi için yapılandırılmış yeni bir ASP.NET Core MVC uygulaması oluşturalım. Uygun bağımlılık enjeksiyonu ve hata işleme ile üretime hazır bir kurulum oluşturacağız. Bu, Visual Studio'da yeni bir .NET projesi olacaktır; bununla birlikte, mevcut bir projeyi de kullanabilirsiniz.

Projenin Oluşturulması

Aşağıdaki komutu çalıştırarak bu projeyi oluşturacağız ve ona uygun bir proje adı vereceğiz:

dotnet new mvc -n PdfGeneratorApp
cd PdfGeneratorApp

Installing IronPDF

ASP.NET'te PDF belgeleri oluşturmaya başlamadan önce, NuGet Paket Yöneticisi Konsolu'nda aşağıdaki satırları çalıştırarak IronPDF'yi projenize ekleyin:

Install-Package IronPdf
Install-Package IronPdf.Extensions.Mvc.Core

NuGet paketleri yapılandırması ve Windows yükleyici dahil olmak üzere ayrıntılı yükleme seçenekleri için resmi belgelere bakın.

Program.cs'de Hizmetleri Yapılandırma

using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Configure IronPDF license (use your license key)
License.LicenseKey = "your-license-key";
// Add MVC services
builder.Services.AddControllersWithViews();
// Register IronPDF services
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Configure ChromePdfRenderer as a service
builder.Services.AddSingleton<ChromePdfRenderer>(provider =>
{
    var renderer = new ChromePdfRenderer();
    // Configure rendering options
    renderer.RenderingOptions.MarginTop = 25;
    renderer.RenderingOptions.MarginBottom = 25;
    renderer.RenderingOptions.MarginLeft = 20;
    renderer.RenderingOptions.MarginRight = 20;
    renderer.RenderingOptions.EnableJavaScript = true;
    renderer.RenderingOptions.RenderDelay = 500; // Wait for JS execution
    return renderer;
});
var app = builder.Build();
// Configure middleware pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseİstisnaHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Configure IronPDF license (use your license key)
License.LicenseKey = "your-license-key";
// Add MVC services
builder.Services.AddControllersWithViews();
// Register IronPDF services
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Configure ChromePdfRenderer as a service
builder.Services.AddSingleton<ChromePdfRenderer>(provider =>
{
    var renderer = new ChromePdfRenderer();
    // Configure rendering options
    renderer.RenderingOptions.MarginTop = 25;
    renderer.RenderingOptions.MarginBottom = 25;
    renderer.RenderingOptions.MarginLeft = 20;
    renderer.RenderingOptions.MarginRight = 20;
    renderer.RenderingOptions.EnableJavaScript = true;
    renderer.RenderingOptions.RenderDelay = 500; // Wait for JS execution
    return renderer;
});
var app = builder.Build();
// Configure middleware pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseİstisnaHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Imports IronPdf
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc.ViewFeatures

Dim builder = WebApplication.CreateBuilder(args)

' Configure IronPDF license (use your license key)
License.LicenseKey = "your-license-key"

' Add MVC services
builder.Services.AddControllersWithViews()

' Register IronPDF services
builder.Services.AddSingleton(Of IHttpContextAccessor, HttpContextAccessor)()
builder.Services.AddSingleton(Of ITempDataProvider, CookieTempDataProvider)()
builder.Services.AddSingleton(Of IRazorViewRenderer, RazorViewRenderer)()

' Configure ChromePdfRenderer as a service
builder.Services.AddSingleton(Of ChromePdfRenderer)(
    Function(provider)
        Dim renderer = New ChromePdfRenderer()
        ' Configure rendering options
        renderer.RenderingOptions.MarginTop = 25
        renderer.RenderingOptions.MarginBottom = 25
        renderer.RenderingOptions.MarginLeft = 20
        renderer.RenderingOptions.MarginRight = 20
        renderer.RenderingOptions.EnableJavaScript = True
        renderer.RenderingOptions.RenderDelay = 500 ' Wait for JS execution
        Return renderer
    End Function)

Dim app = builder.Build()

' Configure middleware pipeline
If Not app.Environment.IsDevelopment() Then
    app.UseExceptionHandler("/Home/Error")
    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

Bu yapılandırma, IronPDF'yi tekil bir hizmet olarak kurarak uygulamanız genelinde verimli kaynak kullanımı sağlar. Özel gereksinimlerinize uyacak şekilde `RenderingOptions` üzerinde değişiklik yapabilirsiniz. Bu noktada, Visual Studio'daki Çözüm Gezgini'ndeki klasör yapınız aşağıdaki gibi görünmelidir:

Razor Görünümlerinden PDF Oluşturma

ASP.NET Core'da yeni PDF belgeleri oluşturmaya yönelik en güçlü yaklaşım, PDF dönüştürme için Razor görünümlerinden yararlanmayı içerir. Bu, özel HTML dosyalarından, web sayfalarından ve diğer kaynaklardan dinamik PDF'ler oluşturmak için tanıdık MVC modellerini, güçlü bir şekilde yazılmış modelleri ve Razor sözdizimini kullanmanıza olanak tanır. Microsoft'un Razor Pages ile ilgili belgelerine göre, bu yaklaşım sayfa odaklı senaryolar için endişelerin en temiz şekilde ayrılmasını sağlar.

Veri Modelinin Oluşturulması

İlk olarak, tipik bir iş belgesini temsil eden kapsamlı bir model oluşturalım:

namespace PdfGeneratorApp.Models
{
    public class InvoiceModel
    {
        public string InvoiceNumber { get; set; }
        public DateTime InvoiceDate { get; set; }
        public DateTime DueDate { get; set; }
        public CompanyInfo Vendor { get; set; }
        public CompanyInfo Customer { get; set; }
        public List<InvoiceItem> Items { get; set; }
        public decimal Subtotal => Items?.Sum(x => x.Total) ?? 0;
        public decimal TaxRate { get; set; }
        public decimal TaxAmount => Subtotal * (TaxRate / 100);
        public decimal Total => Subtotal + TaxAmount;
        public string Notes { get; set; }
        public string PaymentTerms { get; set; }
    }
    public class CompanyInfo
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Email { get; set; }
        public string Phone { 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;
    }
}
namespace PdfGeneratorApp.Models
{
    public class InvoiceModel
    {
        public string InvoiceNumber { get; set; }
        public DateTime InvoiceDate { get; set; }
        public DateTime DueDate { get; set; }
        public CompanyInfo Vendor { get; set; }
        public CompanyInfo Customer { get; set; }
        public List<InvoiceItem> Items { get; set; }
        public decimal Subtotal => Items?.Sum(x => x.Total) ?? 0;
        public decimal TaxRate { get; set; }
        public decimal TaxAmount => Subtotal * (TaxRate / 100);
        public decimal Total => Subtotal + TaxAmount;
        public string Notes { get; set; }
        public string PaymentTerms { get; set; }
    }
    public class CompanyInfo
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Email { get; set; }
        public string Phone { 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;
    }
}
Imports System
Imports System.Collections.Generic
Imports System.Linq

Namespace PdfGeneratorApp.Models
    Public Class InvoiceModel
        Public Property InvoiceNumber As String
        Public Property InvoiceDate As DateTime
        Public Property DueDate As DateTime
        Public Property Vendor As CompanyInfo
        Public Property Customer As CompanyInfo
        Public Property Items As List(Of InvoiceItem)
        Public ReadOnly Property Subtotal As Decimal
            Get
                Return If(Items?.Sum(Function(x) x.Total), 0)
            End Get
        End Property
        Public Property TaxRate As Decimal
        Public ReadOnly Property TaxAmount As Decimal
            Get
                Return Subtotal * (TaxRate / 100)
            End Get
        End Property
        Public ReadOnly Property Total As Decimal
            Get
                Return Subtotal + TaxAmount
            End Get
        End Property
        Public Property Notes As String
        Public Property PaymentTerms As String
    End Class

    Public Class CompanyInfo
        Public Property Name As String
        Public Property Address As String
        Public Property City As String
        Public Property State As String
        Public Property ZipCode As String
        Public Property Email As String
        Public Property Phone As String
    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
End Namespace
$vbLabelText   $csharpLabel

Razor Görünümünü Oluşturma

Views/Invoice/InvoiceTemplate.cshtml adresinde PDF içeriğinizi işleyen bir görünüm oluşturun:

@model PdfGeneratorApp.Models.InvoiceModel
@{
    Layout = null; // PDFs should not use the site layout
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Invoice @Model.InvoiceNumber</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
        }
        .invoice-container {
            max-width: 800px;
            margin: 0 auto;
            padding: 30px;
        }
        .invoice-header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 40px;
            padding-bottom: 20px;
            border-bottom: 2px solid #2c3e50;
        }
        .company-details {
            flex: 1;
        }
        .company-details h1 {
            color: #2c3e50;
            margin-bottom: 10px;
        }
        .invoice-details {
            text-align: right;
        }
        .invoice-details h2 {
            color: #2c3e50;
            font-size: 28px;
            margin-bottom: 10px;
        }
        .invoice-details p {
            margin: 5px 0;
            font-size: 14px;
        }
        .billing-details {
            display: flex;
            justify-content: space-between;
            margin-bottom: 40px;
        }
        .billing-section {
            flex: 1;
        }
        .billing-section h3 {
            color: #2c3e50;
            margin-bottom: 10px;
            font-size: 16px;
            text-transform: uppercase;
        }
        .items-table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 40px;
        }
        .items-table thead {
            background-color: #2c3e50;
            color: white;
        }
        .items-table th,
        .items-table td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }
        .items-table tbody tr:hover {
            background-color: #f5f5f5;
        }
        .text-right {
            text-align: right;
        }
        .invoice-summary {
            display: flex;
            justify-content: flex-end;
            margin-bottom: 40px;
        }
        .summary-table {
            width: 300px;
        }
        .summary-table tr {
            border-bottom: 1px solid #ddd;
        }
        .summary-table td {
            padding: 8px;
        }
        .summary-table .total-row {
            font-weight: bold;
            font-size: 18px;
            color: #2c3e50;
            border-top: 2px solid #2c3e50;
        }
        .invoice-footer {
            margin-top: 60px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
        }
        .footer-notes {
            margin-bottom: 20px;
        }
        .footer-notes h4 {
            color: #2c3e50;
            margin-bottom: 10px;
        }
        @@media print {
            .invoice-container {
                padding: 0;
            }
        }
    </style>
</head>
<body>
    <div class="invoice-container">
        <div class="invoice-header">
            <div class="company-details">
                <h1>@Model.Vendor.Name</h1>
                <p>@Model.Vendor.Address</p>
                <p>@Model.Vendor.City, @Model.Vendor.State @Model.Vendor.ZipCode</p>
                <p>Email: @Model.Vendor.Email</p>
                <p>Phone: @Model.Vendor.Phone</p>
            </div>
            <div class="invoice-details">
                <h2>INVOICE</h2>
                <p><strong>Invoice #:</strong> @Model.InvoiceNumber</p>
                <p><strong>Date:</strong> @Model.InvoiceDate.ToString("MMM dd, yyyy")</p>
                <p><strong>Due Date:</strong> @Model.DueDate.ToString("MMM dd, yyyy")</p>
            </div>
        </div>
        <div class="billing-details">
            <div class="billing-section">
                <h3>Bill To:</h3>
                <p><strong>@Model.Customer.Name</strong></p>
                <p>@Model.Customer.Address</p>
                <p>@Model.Customer.City, @Model.Customer.State @Model.Customer.ZipCode</p>
                <p>@Model.Customer.Email</p>
            </div>
        </div>
        <table class="items-table">
            <thead>
                <tr>
                    <th>Description</th>
                    <th class="text-right">Quantity</th>
                    <th class="text-right">Unit Price</th>
                    <th class="text-right">Total</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Items)
                {
                    <tr>
                        <td>@item.Description</td>
                        <td class="text-right">@item.Quantity</td>
                        <td class="text-right">@item.UnitPrice.ToString("C")</td>
                        <td class="text-right">@item.Total.ToString("C")</td>
                    </tr>
                }
            </tbody>
        </table>
        <div class="invoice-summary">
            <table class="summary-table">
                <tr>
                    <td>Subtotal:</td>
                    <td class="text-right">@Model.Subtotal.ToString("C")</td>
                </tr>
                <tr>
                    <td>Tax (@Model.TaxRate%):</td>
                    <td class="text-right">@Model.TaxAmount.ToString("C")</td>
                </tr>
                <tr class="total-row">
                    <td>Total:</td>
                    <td class="text-right">@Model.Total.ToString("C")</td>
                </tr>
            </table>
        </div>
        @if (!string.IsNullOrEmpty(Model.Notes))
        {
            <div class="invoice-footer">
                <div class="footer-notes">
                    <h4>Notes</h4>
                    <p>@Model.Notes</p>
                </div>
            </div>
        }
        @if (!string.IsNullOrEmpty(Model.PaymentTerms))
        {
            <div class="footer-notes">
                <h4>Payment Terms</h4>
                <p>@Model.PaymentTerms</p>
            </div>
        }
    </div>
</body>
</html>
@model PdfGeneratorApp.Models.InvoiceModel
@{
    Layout = null; // PDFs should not use the site layout
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Invoice @Model.InvoiceNumber</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
        }
        .invoice-container {
            max-width: 800px;
            margin: 0 auto;
            padding: 30px;
        }
        .invoice-header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 40px;
            padding-bottom: 20px;
            border-bottom: 2px solid #2c3e50;
        }
        .company-details {
            flex: 1;
        }
        .company-details h1 {
            color: #2c3e50;
            margin-bottom: 10px;
        }
        .invoice-details {
            text-align: right;
        }
        .invoice-details h2 {
            color: #2c3e50;
            font-size: 28px;
            margin-bottom: 10px;
        }
        .invoice-details p {
            margin: 5px 0;
            font-size: 14px;
        }
        .billing-details {
            display: flex;
            justify-content: space-between;
            margin-bottom: 40px;
        }
        .billing-section {
            flex: 1;
        }
        .billing-section h3 {
            color: #2c3e50;
            margin-bottom: 10px;
            font-size: 16px;
            text-transform: uppercase;
        }
        .items-table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 40px;
        }
        .items-table thead {
            background-color: #2c3e50;
            color: white;
        }
        .items-table th,
        .items-table td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }
        .items-table tbody tr:hover {
            background-color: #f5f5f5;
        }
        .text-right {
            text-align: right;
        }
        .invoice-summary {
            display: flex;
            justify-content: flex-end;
            margin-bottom: 40px;
        }
        .summary-table {
            width: 300px;
        }
        .summary-table tr {
            border-bottom: 1px solid #ddd;
        }
        .summary-table td {
            padding: 8px;
        }
        .summary-table .total-row {
            font-weight: bold;
            font-size: 18px;
            color: #2c3e50;
            border-top: 2px solid #2c3e50;
        }
        .invoice-footer {
            margin-top: 60px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
        }
        .footer-notes {
            margin-bottom: 20px;
        }
        .footer-notes h4 {
            color: #2c3e50;
            margin-bottom: 10px;
        }
        @@media print {
            .invoice-container {
                padding: 0;
            }
        }
    </style>
</head>
<body>
    <div class="invoice-container">
        <div class="invoice-header">
            <div class="company-details">
                <h1>@Model.Vendor.Name</h1>
                <p>@Model.Vendor.Address</p>
                <p>@Model.Vendor.City, @Model.Vendor.State @Model.Vendor.ZipCode</p>
                <p>Email: @Model.Vendor.Email</p>
                <p>Phone: @Model.Vendor.Phone</p>
            </div>
            <div class="invoice-details">
                <h2>INVOICE</h2>
                <p><strong>Invoice #:</strong> @Model.InvoiceNumber</p>
                <p><strong>Date:</strong> @Model.InvoiceDate.ToString("MMM dd, yyyy")</p>
                <p><strong>Due Date:</strong> @Model.DueDate.ToString("MMM dd, yyyy")</p>
            </div>
        </div>
        <div class="billing-details">
            <div class="billing-section">
                <h3>Bill To:</h3>
                <p><strong>@Model.Customer.Name</strong></p>
                <p>@Model.Customer.Address</p>
                <p>@Model.Customer.City, @Model.Customer.State @Model.Customer.ZipCode</p>
                <p>@Model.Customer.Email</p>
            </div>
        </div>
        <table class="items-table">
            <thead>
                <tr>
                    <th>Description</th>
                    <th class="text-right">Quantity</th>
                    <th class="text-right">Unit Price</th>
                    <th class="text-right">Total</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Items)
                {
                    <tr>
                        <td>@item.Description</td>
                        <td class="text-right">@item.Quantity</td>
                        <td class="text-right">@item.UnitPrice.ToString("C")</td>
                        <td class="text-right">@item.Total.ToString("C")</td>
                    </tr>
                }
            </tbody>
        </table>
        <div class="invoice-summary">
            <table class="summary-table">
                <tr>
                    <td>Subtotal:</td>
                    <td class="text-right">@Model.Subtotal.ToString("C")</td>
                </tr>
                <tr>
                    <td>Tax (@Model.TaxRate%):</td>
                    <td class="text-right">@Model.TaxAmount.ToString("C")</td>
                </tr>
                <tr class="total-row">
                    <td>Total:</td>
                    <td class="text-right">@Model.Total.ToString("C")</td>
                </tr>
            </table>
        </div>
        @if (!string.IsNullOrEmpty(Model.Notes))
        {
            <div class="invoice-footer">
                <div class="footer-notes">
                    <h4>Notes</h4>
                    <p>@Model.Notes</p>
                </div>
            </div>
        }
        @if (!string.IsNullOrEmpty(Model.PaymentTerms))
        {
            <div class="footer-notes">
                <h4>Payment Terms</h4>
                <p>@Model.PaymentTerms</p>
            </div>
        }
    </div>
</body>
</html>
$vbLabelText   $csharpLabel

Hata İşleme ile Denetleyicinin Uygulanması

Şimdi kapsamlı hata işleme özelliğine sahip PDF'ler üreten sağlam bir denetleyici oluşturalım:

using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using PdfGeneratorApp.Models;
using System.Diagnostics;
namespace PdfGeneratorApp.Controllers
{
    public class InvoiceController : Controller
    {
        private readonly ILogger<InvoiceController> _logger;
        private readonly IRazorViewRenderer _viewRenderer;
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly IWebHostEnvironment _environment;
        public InvoiceController(
            ILogger<InvoiceController> logger,
            IRazorViewRenderer viewRenderer,
            ChromePdfRenderer pdfRenderer,
            IWebHostEnvironment environment)
        {
            _logger = logger;
            _viewRenderer = viewRenderer;
            _pdfRenderer = pdfRenderer;
            _environment = environment;
        }
        [HttpGet]
        public IActionResult Index()
        {
            // Display a form or list of invoices
            return View();
        }
        [HttpGet]
        public async Task<IActionResult> GenerateInvoice(string invoiceNumber)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                // Validate input
                if (string.IsNullOrEmpty(invoiceNumber))
                {
                    _logger.LogWarning("Invoice generation attempted without invoice number");
                    return BadRequest("Invoice number is required");
                }
                // Generate sample data (in production, fetch from database)
                var invoice = CreateSampleInvoice(invoiceNumber);
                // Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}");
                // Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = true;
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = false;
                // Add custom header with page numbers
                _pdfRenderer.RenderingOptions.TextHeader = new TextHeaderFooter
                {
                    CenterText = $"Invoice {invoice.InvoiceNumber}",
                    DrawDividerLine = true,
                    Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    FontSize = 10
                };
                // Add footer with page numbers
                _pdfRenderer.RenderingOptions.TextFooter = new TextHeaderFooter
                {
                    LeftText = "{date} {time}",
                    RightText = "Page {page} of {total-pages}",
                    DrawDividerLine = true,
                    Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    FontSize = 8
                };
                // Render the view to PDF
                PdfDocument pdf;
                try
                {
                    pdf = _pdfRenderer.RenderRazorViewToPdf(
                        _viewRenderer,
                        "Views/Invoice/InvoiceTemplate.cshtml",
                        invoice);
                }
                catch (İstisna renderEx)
                {
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF");
                    throw new InvalidOperationİstisna("PDF rendering failed. Please check the template.", renderEx);
                }
                // Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp";
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}";
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}";
                pdf.MetaData.Keywords = "invoice, billing, payment";
                pdf.MetaData.CreationDate = DateTime.UtcNow;
                pdf.MetaData.ModifiedDate = DateTime.UtcNow;
                // Optional: Add password protection
                // pdf.SecuritySettings.UserPassword = "user123";
                // pdf.SecuritySettings.OwnerPassword = "owner456";
                // pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                // Log performance metrics
                stopwatch.Stop();
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms");
                // Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf");
                return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}");
                // In development, return detailed error
                if (_environment.IsDevelopment())
                {
                    return StatusCode(500, new
                    {
                        error = "PDF generation failed",
                        message = ex.Message,
                        stackTrace = ex.StackTrace
                    });
                }
                // In production, return generic error
                return StatusCode(500, "An error occurred while generating the PDF");
            }
        }
        private InvoiceModel CreateSampleInvoice(string invoiceNumber)
        {
            return new InvoiceModel
            {
                InvoiceNumber = invoiceNumber,
                InvoiceDate = DateTime.Now,
                DueDate = DateTime.Now.AddDays(30),
                Vendor = new CompanyInfo
                {
                    Name = "Tech Çözüms Inc.",
                    Address = "123 Business Ave",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Email = "billing@techsolutions.com",
                    Phone = "(555) 123-4567"
                },
                Customer = new CompanyInfo
                {
                    Name = "Acme Corporation",
                    Address = "456 Commerce St",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Email = "accounts@acmecorp.com",
                    Phone = "(555) 987-6543"
                },
                Items = new List<InvoiceItem>
                {
                    new InvoiceItem
                    {
                        Description = "Software Development Services - 40 hours",
                        Quantity = 40,
                        UnitPrice = 150.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Project Management - 10 hours",
                        Quantity = 10,
                        UnitPrice = 120.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Quality Assurance Testing",
                        Quantity = 1,
                        UnitPrice = 2500.00m
                    }
                },
                TaxRate = 8.875m,
                Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                PaymentTerms = "Net 30"
            };
        }
    }
}
using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using PdfGeneratorApp.Models;
using System.Diagnostics;
namespace PdfGeneratorApp.Controllers
{
    public class InvoiceController : Controller
    {
        private readonly ILogger<InvoiceController> _logger;
        private readonly IRazorViewRenderer _viewRenderer;
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly IWebHostEnvironment _environment;
        public InvoiceController(
            ILogger<InvoiceController> logger,
            IRazorViewRenderer viewRenderer,
            ChromePdfRenderer pdfRenderer,
            IWebHostEnvironment environment)
        {
            _logger = logger;
            _viewRenderer = viewRenderer;
            _pdfRenderer = pdfRenderer;
            _environment = environment;
        }
        [HttpGet]
        public IActionResult Index()
        {
            // Display a form or list of invoices
            return View();
        }
        [HttpGet]
        public async Task<IActionResult> GenerateInvoice(string invoiceNumber)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                // Validate input
                if (string.IsNullOrEmpty(invoiceNumber))
                {
                    _logger.LogWarning("Invoice generation attempted without invoice number");
                    return BadRequest("Invoice number is required");
                }
                // Generate sample data (in production, fetch from database)
                var invoice = CreateSampleInvoice(invoiceNumber);
                // Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}");
                // Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = true;
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = false;
                // Add custom header with page numbers
                _pdfRenderer.RenderingOptions.TextHeader = new TextHeaderFooter
                {
                    CenterText = $"Invoice {invoice.InvoiceNumber}",
                    DrawDividerLine = true,
                    Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    FontSize = 10
                };
                // Add footer with page numbers
                _pdfRenderer.RenderingOptions.TextFooter = new TextHeaderFooter
                {
                    LeftText = "{date} {time}",
                    RightText = "Page {page} of {total-pages}",
                    DrawDividerLine = true,
                    Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    FontSize = 8
                };
                // Render the view to PDF
                PdfDocument pdf;
                try
                {
                    pdf = _pdfRenderer.RenderRazorViewToPdf(
                        _viewRenderer,
                        "Views/Invoice/InvoiceTemplate.cshtml",
                        invoice);
                }
                catch (İstisna renderEx)
                {
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF");
                    throw new InvalidOperationİstisna("PDF rendering failed. Please check the template.", renderEx);
                }
                // Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp";
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}";
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}";
                pdf.MetaData.Keywords = "invoice, billing, payment";
                pdf.MetaData.CreationDate = DateTime.UtcNow;
                pdf.MetaData.ModifiedDate = DateTime.UtcNow;
                // Optional: Add password protection
                // pdf.SecuritySettings.UserPassword = "user123";
                // pdf.SecuritySettings.OwnerPassword = "owner456";
                // pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                // Log performance metrics
                stopwatch.Stop();
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms");
                // Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf");
                return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}");
                // In development, return detailed error
                if (_environment.IsDevelopment())
                {
                    return StatusCode(500, new
                    {
                        error = "PDF generation failed",
                        message = ex.Message,
                        stackTrace = ex.StackTrace
                    });
                }
                // In production, return generic error
                return StatusCode(500, "An error occurred while generating the PDF");
            }
        }
        private InvoiceModel CreateSampleInvoice(string invoiceNumber)
        {
            return new InvoiceModel
            {
                InvoiceNumber = invoiceNumber,
                InvoiceDate = DateTime.Now,
                DueDate = DateTime.Now.AddDays(30),
                Vendor = new CompanyInfo
                {
                    Name = "Tech Çözüms Inc.",
                    Address = "123 Business Ave",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Email = "billing@techsolutions.com",
                    Phone = "(555) 123-4567"
                },
                Customer = new CompanyInfo
                {
                    Name = "Acme Corporation",
                    Address = "456 Commerce St",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Email = "accounts@acmecorp.com",
                    Phone = "(555) 987-6543"
                },
                Items = new List<InvoiceItem>
                {
                    new InvoiceItem
                    {
                        Description = "Software Development Services - 40 hours",
                        Quantity = 40,
                        UnitPrice = 150.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Project Management - 10 hours",
                        Quantity = 10,
                        UnitPrice = 120.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Quality Assurance Testing",
                        Quantity = 1,
                        UnitPrice = 2500.00m
                    }
                },
                TaxRate = 8.875m,
                Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                PaymentTerms = "Net 30"
            };
        }
    }
}
Imports IronPdf
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc
Imports PdfGeneratorApp.Models
Imports System.Diagnostics

Namespace PdfGeneratorApp.Controllers

    Public Class InvoiceController
        Inherits Controller

        Private ReadOnly _logger As ILogger(Of InvoiceController)
        Private ReadOnly _viewRenderer As IRazorViewRenderer
        Private ReadOnly _pdfRenderer As ChromePdfRenderer
        Private ReadOnly _environment As IWebHostEnvironment

        Public Sub New(logger As ILogger(Of InvoiceController), viewRenderer As IRazorViewRenderer, pdfRenderer As ChromePdfRenderer, environment As IWebHostEnvironment)
            _logger = logger
            _viewRenderer = viewRenderer
            _pdfRenderer = pdfRenderer
            _environment = environment
        End Sub

        <HttpGet>
        Public Function Index() As IActionResult
            ' Display a form or list of invoices
            Return View()
        End Function

        <HttpGet>
        Public Async Function GenerateInvoice(invoiceNumber As String) As Task(Of IActionResult)
            Dim stopwatch = Stopwatch.StartNew()
            Try
                ' Validate input
                If String.IsNullOrEmpty(invoiceNumber) Then
                    _logger.LogWarning("Invoice generation attempted without invoice number")
                    Return BadRequest("Invoice number is required")
                End If

                ' Generate sample data (in production, fetch from database)
                Dim invoice = CreateSampleInvoice(invoiceNumber)

                ' Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}")

                ' Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = True
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = False

                ' Add custom header with page numbers
                _pdfRenderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
                    .CenterText = $"Invoice {invoice.InvoiceNumber}",
                    .DrawDividerLine = True,
                    .Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    .FontSize = 10
                }

                ' Add footer with page numbers
                _pdfRenderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
                    .LeftText = "{date} {time}",
                    .RightText = "Page {page} of {total-pages}",
                    .DrawDividerLine = True,
                    .Font = IronSoftware.Drawing.FontTypes.Helvetica,
                    .FontSize = 8
                }

                ' Render the view to PDF
                Dim pdf As PdfDocument
                Try
                    pdf = _pdfRenderer.RenderRazorViewToPdf(_viewRenderer, "Views/Invoice/InvoiceTemplate.cshtml", invoice)
                Catch renderEx As Exception
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF")
                    Throw New InvalidOperationException("PDF rendering failed. Please check the template.", renderEx)
                End Try

                ' Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp"
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}"
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}"
                pdf.MetaData.Keywords = "invoice, billing, payment"
                pdf.MetaData.CreationDate = DateTime.UtcNow
                pdf.MetaData.ModifiedDate = DateTime.UtcNow

                ' Optional: Add password protection
                ' pdf.SecuritySettings.UserPassword = "user123"
                ' pdf.SecuritySettings.OwnerPassword = "owner456"
                ' pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights

                ' Log performance metrics
                stopwatch.Stop()
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms")

                ' Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf")
                Return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf")
            Catch ex As Exception
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}")

                ' In development, return detailed error
                If _environment.IsDevelopment() Then
                    Return StatusCode(500, New With {
                        .error = "PDF generation failed",
                        .message = ex.Message,
                        .stackTrace = ex.StackTrace
                    })
                End If

                ' In production, return generic error
                Return StatusCode(500, "An error occurred while generating the PDF")
            End Try
        End Function

        Private Function CreateSampleInvoice(invoiceNumber As String) As InvoiceModel
            Return New InvoiceModel With {
                .InvoiceNumber = invoiceNumber,
                .InvoiceDate = DateTime.Now,
                .DueDate = DateTime.Now.AddDays(30),
                .Vendor = New CompanyInfo With {
                    .Name = "Tech Çözüms Inc.",
                    .Address = "123 Business Ave",
                    .City = "New York",
                    .State = "NY",
                    .ZipCode = "10001",
                    .Email = "billing@techsolutions.com",
                    .Phone = "(555) 123-4567"
                },
                .Customer = New CompanyInfo With {
                    .Name = "Acme Corporation",
                    .Address = "456 Commerce St",
                    .City = "Los Angeles",
                    .State = "CA",
                    .ZipCode = "90001",
                    .Email = "accounts@acmecorp.com",
                    .Phone = "(555) 987-6543"
                },
                .Items = New List(Of InvoiceItem) From {
                    New InvoiceItem With {
                        .Description = "Software Development Services - 40 hours",
                        .Quantity = 40,
                        .UnitPrice = 150.0D
                    },
                    New InvoiceItem With {
                        .Description = "Project Management - 10 hours",
                        .Quantity = 10,
                        .UnitPrice = 120.0D
                    },
                    New InvoiceItem With {
                        .Description = "Quality Assurance Testing",
                        .Quantity = 1,
                        .UnitPrice = 2500.0D
                    }
                },
                .TaxRate = 8.875D,
                .Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                .PaymentTerms = "Net 30"
            }
        End Function

    End Class

End Namespace
$vbLabelText   $csharpLabel

Kod Açıklaması

Yukarıdaki PDF oluşturucuyu test etmek ve çalıştırmak için projeyi başlatın ve aşağıdaki URL'yi girin: https://localhost:[port]/Invoice/GenerateInvoice?invoiceNumber=055 faturayı oluşturmak için. Lütfen bağlantı noktasını uygulamayı barındırdığınız gerçek bağlantı noktası numarasıyla değiştirmeyi unutmayın.

Çıktı

!C# Kullanarak ASP.NET'te PDF Oluşturma: Şekil 4 - PDF Çıktısı (PDF/A)

Maksimum Verimlilik için Web API Uç Noktalarından PDF'ler Nasıl Döndürülür?

PDF'lerin RESTful API'ler aracılığıyla sunulmasını gerektiren uygulamalar için, uygun bellek yönetimi ile verimli PDF dağıtımının nasıl uygulanacağı aşağıda açıklanmıştır. Bu yaklaşım özellikle mikro hizmetler oluştururken veya .NET Core Web API denetleyicilerinde PDF oluşturmanız gerektiğinde kullanışlıdır:

using Microsoft.AspNetCore.Mvc;
using IronPdf;
using System.IO;
namespace PdfGeneratorApp.Controllers.Api
{
    [ApiController]
    [Route("api/[controller]")]
    public class PdfApiController : ControllerBase
    {
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly ILogger<PdfApiController> _logger;
        public PdfApiController(
            ChromePdfRenderer pdfRenderer,
            ILogger<PdfApiController> logger)
        {
            _pdfRenderer = pdfRenderer;
            _logger = logger;
        }
        [HttpPost("generate-report")]
        public async Task<IActionResult> GenerateReport([FromBody] ReportRequest request)
        {
            try
            {
                // Validate request
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
                // Build HTML content dynamically
                var htmlContent = BuildReportHtml(request);
                // Generate PDF with memory-efficient streaming
                using var pdfDocument = _pdfRenderer.RenderHtmlAsPdf(htmlContent);
                // Apply compression for smaller file size
                pdfDocument.CompressImages(60); // 60% quality
                // Stream the PDF directly to response
                var stream = new MemoryStream();
                pdfDocument.SaveAs(stream);
                stream.Position = 0;
                _logger.LogInformation($"Report generated for {request.ReportType}");
                return new FileStreamResult(stream, "application/pdf")
                {
                    FileDownloadName = $"Report_{DateTime.Now:yyyyMMdd_HHmmss}.pdf"
                };
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, "Failed to generate report");
                return StatusCode(500, new { error = "Report generation failed" });
            }
        }
        [HttpGet("download/{documentId}")]
        public async Task<IActionResult> DownloadDocument(string documentId)
        {
            try
            {
                // In production, retrieve document from database or storage
                var documentPath = Path.Combine("wwwroot", "documents", $"{documentId}.pdf");
                if (!System.IO.File.Exists(documentPath))
                {
                    return NotFound(new { error = "Document not found" });
                }
                var memory = new MemoryStream();
                using (var stream = new FileStream(documentPath, FileMode.Open))
                {
                    await stream.CopyToAsync(memory);
                }
                memory.Position = 0;
                return File(memory, "application/pdf", $"Document_{documentId}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Failed to download document {documentId}");
                return StatusCode(500, new { error = "Download failed" });
            }
        }
        private string BuildReportHtml(ReportRequest request)
        {
            return $@"
                <!DOCTYPE html>
                <html>
                <head>
                    <style>
                        body {{ 
                            font-family: Arial, sans-serif; 
                            margin: 40px;
                        }}
                        h1 {{ 
                            color: #2c3e50; 
                            border-bottom: 2px solid #3498db;
                            padding-bottom: 10px;
                        }}
                        .report-date {{ 
                            color: #7f8c8d; 
                            font-size: 14px;
                        }}
                        .data-table {{
                            width: 100%;
                            border-collapse: collapse;
                            margin-top: 20px;
                        }}
                        .data-table th, .data-table td {{
                            border: 1px solid #ddd;
                            padding: 12px;
                            text-align: left;
                        }}
                        .data-table th {{
                            background-color: #3498db;
                            color: white;
                        }}
                    </style>
                </head>
                <body>
                    <h1>{request.ReportType} Report</h1>
                    <p class='report-date'>Generated: {DateTime.Now:MMMM dd, yyyy HH:mm}</p>
                    <p>{request.Description}</p>
                    {GenerateDataTable(request.Data)}
                </body>
                </html>";
        }
        private string GenerateDataTable(List<ReportDataItem> data)
        {
            if (data == null || !data.Any())
                return "<p>No data available</p>";
            var table = "<table class='data-table'><thead><tr>";
            // Add headers
            foreach (var prop in typeof(ReportDataItem).GetProperties())
            {
                table += $"<th>{prop.Name}</th>";
            }
            table += "</tr></thead><tbody>";
            // Add data rows
            foreach (var item in data)
            {
                table += "<tr>";
                foreach (var prop in typeof(ReportDataItem).GetProperties())
                {
                    var value = prop.GetValue(item) ?? "";
                    table += $"<td>{value}</td>";
                }
                table += "</tr>";
            }
            table += "</tbody></table>";
            return table;
        }
    }
    public class ReportRequest
    {
        public string ReportType { get; set; }
        public string Description { get; set; }
        public List<ReportDataItem> Data { get; set; }
    }
    public class ReportDataItem
    {
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Value { get; set; }
        public DateTime Date { get; set; }
    }
}
using Microsoft.AspNetCore.Mvc;
using IronPdf;
using System.IO;
namespace PdfGeneratorApp.Controllers.Api
{
    [ApiController]
    [Route("api/[controller]")]
    public class PdfApiController : ControllerBase
    {
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly ILogger<PdfApiController> _logger;
        public PdfApiController(
            ChromePdfRenderer pdfRenderer,
            ILogger<PdfApiController> logger)
        {
            _pdfRenderer = pdfRenderer;
            _logger = logger;
        }
        [HttpPost("generate-report")]
        public async Task<IActionResult> GenerateReport([FromBody] ReportRequest request)
        {
            try
            {
                // Validate request
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
                // Build HTML content dynamically
                var htmlContent = BuildReportHtml(request);
                // Generate PDF with memory-efficient streaming
                using var pdfDocument = _pdfRenderer.RenderHtmlAsPdf(htmlContent);
                // Apply compression for smaller file size
                pdfDocument.CompressImages(60); // 60% quality
                // Stream the PDF directly to response
                var stream = new MemoryStream();
                pdfDocument.SaveAs(stream);
                stream.Position = 0;
                _logger.LogInformation($"Report generated for {request.ReportType}");
                return new FileStreamResult(stream, "application/pdf")
                {
                    FileDownloadName = $"Report_{DateTime.Now:yyyyMMdd_HHmmss}.pdf"
                };
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, "Failed to generate report");
                return StatusCode(500, new { error = "Report generation failed" });
            }
        }
        [HttpGet("download/{documentId}")]
        public async Task<IActionResult> DownloadDocument(string documentId)
        {
            try
            {
                // In production, retrieve document from database or storage
                var documentPath = Path.Combine("wwwroot", "documents", $"{documentId}.pdf");
                if (!System.IO.File.Exists(documentPath))
                {
                    return NotFound(new { error = "Document not found" });
                }
                var memory = new MemoryStream();
                using (var stream = new FileStream(documentPath, FileMode.Open))
                {
                    await stream.CopyToAsync(memory);
                }
                memory.Position = 0;
                return File(memory, "application/pdf", $"Document_{documentId}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Failed to download document {documentId}");
                return StatusCode(500, new { error = "Download failed" });
            }
        }
        private string BuildReportHtml(ReportRequest request)
        {
            return $@"
                <!DOCTYPE html>
                <html>
                <head>
                    <style>
                        body {{ 
                            font-family: Arial, sans-serif; 
                            margin: 40px;
                        }}
                        h1 {{ 
                            color: #2c3e50; 
                            border-bottom: 2px solid #3498db;
                            padding-bottom: 10px;
                        }}
                        .report-date {{ 
                            color: #7f8c8d; 
                            font-size: 14px;
                        }}
                        .data-table {{
                            width: 100%;
                            border-collapse: collapse;
                            margin-top: 20px;
                        }}
                        .data-table th, .data-table td {{
                            border: 1px solid #ddd;
                            padding: 12px;
                            text-align: left;
                        }}
                        .data-table th {{
                            background-color: #3498db;
                            color: white;
                        }}
                    </style>
                </head>
                <body>
                    <h1>{request.ReportType} Report</h1>
                    <p class='report-date'>Generated: {DateTime.Now:MMMM dd, yyyy HH:mm}</p>
                    <p>{request.Description}</p>
                    {GenerateDataTable(request.Data)}
                </body>
                </html>";
        }
        private string GenerateDataTable(List<ReportDataItem> data)
        {
            if (data == null || !data.Any())
                return "<p>No data available</p>";
            var table = "<table class='data-table'><thead><tr>";
            // Add headers
            foreach (var prop in typeof(ReportDataItem).GetProperties())
            {
                table += $"<th>{prop.Name}</th>";
            }
            table += "</tr></thead><tbody>";
            // Add data rows
            foreach (var item in data)
            {
                table += "<tr>";
                foreach (var prop in typeof(ReportDataItem).GetProperties())
                {
                    var value = prop.GetValue(item) ?? "";
                    table += $"<td>{value}</td>";
                }
                table += "</tr>";
            }
            table += "</tbody></table>";
            return table;
        }
    }
    public class ReportRequest
    {
        public string ReportType { get; set; }
        public string Description { get; set; }
        public List<ReportDataItem> Data { get; set; }
    }
    public class ReportDataItem
    {
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Value { get; set; }
        public DateTime Date { get; set; }
    }
}
Imports Microsoft.AspNetCore.Mvc
Imports IronPdf
Imports System.IO

Namespace PdfGeneratorApp.Controllers.Api

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

        Private ReadOnly _pdfRenderer As ChromePdfRenderer
        Private ReadOnly _logger As ILogger(Of PdfApiController)

        Public Sub New(pdfRenderer As ChromePdfRenderer, logger As ILogger(Of PdfApiController))
            _pdfRenderer = pdfRenderer
            _logger = logger
        End Sub

        <HttpPost("generate-report")>
        Public Async Function GenerateReport(<FromBody> request As ReportRequest) As Task(Of IActionResult)
            Try
                ' Validate request
                If Not ModelState.IsValid Then
                    Return BadRequest(ModelState)
                End If

                ' Build HTML content dynamically
                Dim htmlContent = BuildReportHtml(request)

                ' Generate PDF with memory-efficient streaming
                Using pdfDocument = _pdfRenderer.RenderHtmlAsPdf(htmlContent)
                    ' Apply compression for smaller file size
                    pdfDocument.CompressImages(60) ' 60% quality

                    ' Stream the PDF directly to response
                    Dim stream = New MemoryStream()
                    pdfDocument.SaveAs(stream)
                    stream.Position = 0
                    _logger.LogInformation($"Report generated for {request.ReportType}")
                    Return New FileStreamResult(stream, "application/pdf") With {
                        .FileDownloadName = $"Report_{DateTime.Now:yyyyMMdd_HHmmss}.pdf"
                    }
                End Using
            Catch ex As Exception
                _logger.LogError(ex, "Failed to generate report")
                Return StatusCode(500, New With {.error = "Report generation failed"})
            End Try
        End Function

        <HttpGet("download/{documentId}")>
        Public Async Function DownloadDocument(documentId As String) As Task(Of IActionResult)
            Try
                ' In production, retrieve document from database or storage
                Dim documentPath = Path.Combine("wwwroot", "documents", $"{documentId}.pdf")
                If Not System.IO.File.Exists(documentPath) Then
                    Return NotFound(New With {.error = "Document not found"})
                End If

                Dim memory = New MemoryStream()
                Using stream = New FileStream(documentPath, FileMode.Open)
                    Await stream.CopyToAsync(memory)
                End Using
                memory.Position = 0
                Return File(memory, "application/pdf", $"Document_{documentId}.pdf")
            Catch ex As Exception
                _logger.LogError(ex, $"Failed to download document {documentId}")
                Return StatusCode(500, New With {.error = "Download failed"})
            End Try
        End Function

        Private Function BuildReportHtml(request As ReportRequest) As String
            Return $"
                <!DOCTYPE html>
                <html>
                <head>
                    <style>
                        body {{ 
                            font-family: Arial, sans-serif; 
                            margin: 40px;
                        }}
                        h1 {{ 
                            color: #2c3e50; 
                            border-bottom: 2px solid #3498db;
                            padding-bottom: 10px;
                        }}
                        .report-date {{ 
                            color: #7f8c8d; 
                            font-size: 14px;
                        }}
                        .data-table {{
                            width: 100%;
                            border-collapse: collapse;
                            margin-top: 20px;
                        }}
                        .data-table th, .data-table td {{
                            border: 1px solid #ddd;
                            padding: 12px;
                            text-align: left;
                        }}
                        .data-table th {{
                            background-color: #3498db;
                            color: white;
                        }}
                    </style>
                </head>
                <body>
                    <h1>{request.ReportType} Report</h1>
                    <p class='report-date'>Generated: {DateTime.Now:MMMM dd, yyyy HH:mm}</p>
                    <p>{request.Description}</p>
                    {GenerateDataTable(request.Data)}
                </body>
                </html>"
        End Function

        Private Function GenerateDataTable(data As List(Of ReportDataItem)) As String
            If data Is Nothing OrElse Not data.Any() Then
                Return "<p>No data available</p>"
            End If

            Dim table = "<table class='data-table'><thead><tr>"
            ' Add headers
            For Each prop In GetType(ReportDataItem).GetProperties()
                table += $"<th>{prop.Name}</th>"
            Next
            table += "</tr></thead><tbody>"
            ' Add data rows
            For Each item In data
                table += "<tr>"
                For Each prop In GetType(ReportDataItem).GetProperties()
                    Dim value = If(prop.GetValue(item), "")
                    table += $"<td>{value}</td>"
                Next
                table += "</tr>"
            Next
            table += "</tbody></table>"
            Return table
        End Function

    End Class

    Public Class ReportRequest
        Public Property ReportType As String
        Public Property Description As String
        Public Property Data As List(Of ReportDataItem)
    End Class

    Public Class ReportDataItem
        Public Property Name As String
        Public Property Category As String
        Public Property Value As Decimal
        Public Property Date As DateTime
    End Class

End Namespace
$vbLabelText   $csharpLabel

Professional Üstbilgiler, Altbilgiler ve Stil Ekleme

Professional PDF'ler tutarlı üstbilgiler, altbilgiler ve stil gerektirir. IronPDF hem basit metin tabanlı hem de gelişmiş HTML tabanlı seçenekler sunar. HTML biçimlendirmesini şekillendirmek için CSS stillerini kullanarak özel PDF üstbilgileri ve altbilgileri oluşturabiliriz. Aşağıdaki kod parçacığı, mevcut projemizde bunu nasıl kullanabileceğimizi araştırıyor:

using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using PdfGeneratorApp.Models;
using PdfGeneratorApp.Services;
using System.Diagnostics;
namespace PdfGeneratorApp.Controllers
{
    public class InvoiceController : Controller
    {
        private readonly ILogger<InvoiceController> _logger;
        private readonly IRazorViewRenderer _viewRenderer;
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly PdfFormattingService _pdfFormattingService;
        private readonly IWebHostEnvironment _environment;
        public InvoiceController(
            ILogger<InvoiceController> logger,
            IRazorViewRenderer viewRenderer,
            ChromePdfRenderer pdfRenderer,
            PdfFormattingService pdfFormattingService,
            IWebHostEnvironment environment)
        {
            _logger = logger;
            _viewRenderer = viewRenderer;
            _pdfRenderer = pdfRenderer;
            _pdfFormattingService = pdfFormattingService;
            _environment = environment;
        }
        [HttpGet]
        public IActionResult Index()
        {
            // Display a form or list of invoices
            return View();
        }
        private void ConfigurePdfRendererOptions(ChromePdfRenderer renderer, InvoiceModel invoice, PdfStylingOptions options)
        {
            // Margins
            renderer.RenderingOptions.MarginTop = options.MarginTop;
            renderer.RenderingOptions.MarginBottom = options.MarginBottom;
            renderer.RenderingOptions.MarginLeft = options.MarginLeft;
            renderer.RenderingOptions.MarginRight = options.MarginRight;
            // Header
            if (options.UseHtmlHeader)
            {
                renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
                {
                    MaxHeight = 50,
                    HtmlFragment = $@"
                <div style='width: 100%; font-size: 12px; font-family: Arial;'>
                    <div style='float: left; width: 50%;'>

                        <img src='https://ironpdf.com/img/products/ironpdf-logo-text-dotnet.svg' height='40' />
                    </div>
                    <div style='float: right; width: 50%; text-align: right;'>
                        <strong>Invoice {invoice.InvoiceNumber}</strong><br/>
                        Generated: {DateTime.Now:yyyy-MM-dd}
                    </div>
                </div>",
                    LoadStylesAndCSSFromMainHtmlDocument = true
                };
            }
            else
            {
                renderer.RenderingOptions.TextHeader = new TextHeaderFooter
                {
                    CenterText = options.HeaderText,
                    Font = IronSoftware.Drawing.FontTypes.Arial,
                    FontSize = 12,
                    DrawDividerLine = true
                };
            }
            // Footer
            renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
            {
                MaxHeight = 30,
                HtmlFragment = @"
            <div style='width: 100%; font-size: 10px; color: #666;'>
                <div style='float: left; width: 33%;'>
                    © 2025 Your Company
                </div>
                <div style='float: center; width: 33%; text-align: center;'>
                    yourwebsite.com
                </div>
                <div style='float: right; width: 33%; text-align: right;'>
                    Page {page} of {total-pages}
                </div>
            </div>"
            };
            // Optional: Add watermark here (IronPDF supports adding after PDF is generated, so keep it as-is)
            // Margins, paper size etc., can also be set here if needed
            renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
            renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
            renderer.RenderingOptions.PrintHtmlBackgrounds = true;
        }
        [HttpGet]
        public async Task<IActionResult> GenerateInvoice(string invoiceNumber)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                // Validate input
                if (string.IsNullOrEmpty(invoiceNumber))
                {
                    _logger.LogWarning("Invoice generation attempted without invoice number");
                    return BadRequest("Invoice number is required");
                }
                // Generate sample data (in production, fetch from database)
                var invoice = CreateSampleInvoice(invoiceNumber);
                // Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}");
                // Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = true;
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = false;
                var options = new PdfStylingOptions
                {
                    MarginTop = 25,
                    MarginBottom = 25,
                    MarginLeft = 20,
                    MarginRight = 20,
                    UseHtmlHeader = true,
                    HeaderText = $"Invoice {invoice.InvoiceNumber}",
                    AddWatermark = false,
                    ForcePageBreaks = false
                };
                // Apply the styling to the renderer BEFORE rendering PDF
                ConfigurePdfRendererOptions(_pdfRenderer, invoice, options);
                // Render the view to PDF
                PdfDocument pdf;
                try
                {
                    pdf = _pdfRenderer.RenderRazorViewToPdf(
                        _viewRenderer,
                        "Views/Invoice/InvoiceTemplate.cshtml",
                        invoice);
                }
                catch (İstisna renderEx)
                {
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF");
                    throw new InvalidOperationİstisna("PDF rendering failed. Please check the template.", renderEx);
                }
                // Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp";
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}";
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}";
                pdf.MetaData.Keywords = "invoice, billing, payment";
                pdf.MetaData.CreationDate = DateTime.UtcNow;
                pdf.MetaData.ModifiedDate = DateTime.UtcNow;
                // Optional: Add password protection
                // pdf.SecuritySettings.UserPassword = "user123";
                // pdf.SecuritySettings.OwnerPassword = "owner456";
                // pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                // Log performance metrics
                stopwatch.Stop();
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms");
                // Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf");
                return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}");
                // In development, return detailed error
                if (_environment.IsDevelopment())
                {
                    return StatusCode(500, new
                    {
                        error = "PDF generation failed",
                        message = ex.Message,
                        stackTrace = ex.StackTrace
                    });
                }
                // In production, return generic error
                return StatusCode(500, "An error occurred while generating the PDF");
            }
        }
        private InvoiceModel CreateSampleInvoice(string invoiceNumber)
        {
            return new InvoiceModel
            {
                InvoiceNumber = invoiceNumber,
                InvoiceDate = DateTime.Now,
                DueDate = DateTime.Now.AddDays(30),
                Vendor = new CompanyInfo
                {
                    Name = "Tech Çözüms Inc.",
                    Address = "123 Business Ave",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Email = "billing@techsolutions.com",
                    Phone = "(555) 123-4567"
                },
                Customer = new CompanyInfo
                {
                    Name = "Acme Corporation",
                    Address = "456 Commerce St",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Email = "accounts@acmecorp.com",
                    Phone = "(555) 987-6543"
                },
                Items = new List<InvoiceItem>
                {
                    new InvoiceItem
                    {
                        Description = "Software Development Services - 40 hours",
                        Quantity = 40,
                        UnitPrice = 150.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Project Management - 10 hours",
                        Quantity = 10,
                        UnitPrice = 120.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Quality Assurance Testing",
                        Quantity = 1,
                        UnitPrice = 2500.00m
                    }
                },
                TaxRate = 8.875m,
                Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                PaymentTerms = "Net 30"
            };
        }
    }
}
using IronPdf;
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using PdfGeneratorApp.Models;
using PdfGeneratorApp.Services;
using System.Diagnostics;
namespace PdfGeneratorApp.Controllers
{
    public class InvoiceController : Controller
    {
        private readonly ILogger<InvoiceController> _logger;
        private readonly IRazorViewRenderer _viewRenderer;
        private readonly ChromePdfRenderer _pdfRenderer;
        private readonly PdfFormattingService _pdfFormattingService;
        private readonly IWebHostEnvironment _environment;
        public InvoiceController(
            ILogger<InvoiceController> logger,
            IRazorViewRenderer viewRenderer,
            ChromePdfRenderer pdfRenderer,
            PdfFormattingService pdfFormattingService,
            IWebHostEnvironment environment)
        {
            _logger = logger;
            _viewRenderer = viewRenderer;
            _pdfRenderer = pdfRenderer;
            _pdfFormattingService = pdfFormattingService;
            _environment = environment;
        }
        [HttpGet]
        public IActionResult Index()
        {
            // Display a form or list of invoices
            return View();
        }
        private void ConfigurePdfRendererOptions(ChromePdfRenderer renderer, InvoiceModel invoice, PdfStylingOptions options)
        {
            // Margins
            renderer.RenderingOptions.MarginTop = options.MarginTop;
            renderer.RenderingOptions.MarginBottom = options.MarginBottom;
            renderer.RenderingOptions.MarginLeft = options.MarginLeft;
            renderer.RenderingOptions.MarginRight = options.MarginRight;
            // Header
            if (options.UseHtmlHeader)
            {
                renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
                {
                    MaxHeight = 50,
                    HtmlFragment = $@"
                <div style='width: 100%; font-size: 12px; font-family: Arial;'>
                    <div style='float: left; width: 50%;'>

                        <img src='https://ironpdf.com/img/products/ironpdf-logo-text-dotnet.svg' height='40' />
                    </div>
                    <div style='float: right; width: 50%; text-align: right;'>
                        <strong>Invoice {invoice.InvoiceNumber}</strong><br/>
                        Generated: {DateTime.Now:yyyy-MM-dd}
                    </div>
                </div>",
                    LoadStylesAndCSSFromMainHtmlDocument = true
                };
            }
            else
            {
                renderer.RenderingOptions.TextHeader = new TextHeaderFooter
                {
                    CenterText = options.HeaderText,
                    Font = IronSoftware.Drawing.FontTypes.Arial,
                    FontSize = 12,
                    DrawDividerLine = true
                };
            }
            // Footer
            renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
            {
                MaxHeight = 30,
                HtmlFragment = @"
            <div style='width: 100%; font-size: 10px; color: #666;'>
                <div style='float: left; width: 33%;'>
                    © 2025 Your Company
                </div>
                <div style='float: center; width: 33%; text-align: center;'>
                    yourwebsite.com
                </div>
                <div style='float: right; width: 33%; text-align: right;'>
                    Page {page} of {total-pages}
                </div>
            </div>"
            };
            // Optional: Add watermark here (IronPDF supports adding after PDF is generated, so keep it as-is)
            // Margins, paper size etc., can also be set here if needed
            renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
            renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
            renderer.RenderingOptions.PrintHtmlBackgrounds = true;
        }
        [HttpGet]
        public async Task<IActionResult> GenerateInvoice(string invoiceNumber)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                // Validate input
                if (string.IsNullOrEmpty(invoiceNumber))
                {
                    _logger.LogWarning("Invoice generation attempted without invoice number");
                    return BadRequest("Invoice number is required");
                }
                // Generate sample data (in production, fetch from database)
                var invoice = CreateSampleInvoice(invoiceNumber);
                // Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}");
                // Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = true;
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = false;
                var options = new PdfStylingOptions
                {
                    MarginTop = 25,
                    MarginBottom = 25,
                    MarginLeft = 20,
                    MarginRight = 20,
                    UseHtmlHeader = true,
                    HeaderText = $"Invoice {invoice.InvoiceNumber}",
                    AddWatermark = false,
                    ForcePageBreaks = false
                };
                // Apply the styling to the renderer BEFORE rendering PDF
                ConfigurePdfRendererOptions(_pdfRenderer, invoice, options);
                // Render the view to PDF
                PdfDocument pdf;
                try
                {
                    pdf = _pdfRenderer.RenderRazorViewToPdf(
                        _viewRenderer,
                        "Views/Invoice/InvoiceTemplate.cshtml",
                        invoice);
                }
                catch (İstisna renderEx)
                {
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF");
                    throw new InvalidOperationİstisna("PDF rendering failed. Please check the template.", renderEx);
                }
                // Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp";
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}";
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}";
                pdf.MetaData.Keywords = "invoice, billing, payment";
                pdf.MetaData.CreationDate = DateTime.UtcNow;
                pdf.MetaData.ModifiedDate = DateTime.UtcNow;
                // Optional: Add password protection
                // pdf.SecuritySettings.UserPassword = "user123";
                // pdf.SecuritySettings.OwnerPassword = "owner456";
                // pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                // Log performance metrics
                stopwatch.Stop();
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms");
                // Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf");
                return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf");
            }
            catch (İstisna ex)
            {
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}");
                // In development, return detailed error
                if (_environment.IsDevelopment())
                {
                    return StatusCode(500, new
                    {
                        error = "PDF generation failed",
                        message = ex.Message,
                        stackTrace = ex.StackTrace
                    });
                }
                // In production, return generic error
                return StatusCode(500, "An error occurred while generating the PDF");
            }
        }
        private InvoiceModel CreateSampleInvoice(string invoiceNumber)
        {
            return new InvoiceModel
            {
                InvoiceNumber = invoiceNumber,
                InvoiceDate = DateTime.Now,
                DueDate = DateTime.Now.AddDays(30),
                Vendor = new CompanyInfo
                {
                    Name = "Tech Çözüms Inc.",
                    Address = "123 Business Ave",
                    City = "New York",
                    State = "NY",
                    ZipCode = "10001",
                    Email = "billing@techsolutions.com",
                    Phone = "(555) 123-4567"
                },
                Customer = new CompanyInfo
                {
                    Name = "Acme Corporation",
                    Address = "456 Commerce St",
                    City = "Los Angeles",
                    State = "CA",
                    ZipCode = "90001",
                    Email = "accounts@acmecorp.com",
                    Phone = "(555) 987-6543"
                },
                Items = new List<InvoiceItem>
                {
                    new InvoiceItem
                    {
                        Description = "Software Development Services - 40 hours",
                        Quantity = 40,
                        UnitPrice = 150.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Project Management - 10 hours",
                        Quantity = 10,
                        UnitPrice = 120.00m
                    },
                    new InvoiceItem
                    {
                        Description = "Quality Assurance Testing",
                        Quantity = 1,
                        UnitPrice = 2500.00m
                    }
                },
                TaxRate = 8.875m,
                Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                PaymentTerms = "Net 30"
            };
        }
    }
}
Imports IronPdf
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc
Imports PdfGeneratorApp.Models
Imports PdfGeneratorApp.Services
Imports System.Diagnostics

Namespace PdfGeneratorApp.Controllers

    Public Class InvoiceController
        Inherits Controller

        Private ReadOnly _logger As ILogger(Of InvoiceController)
        Private ReadOnly _viewRenderer As IRazorViewRenderer
        Private ReadOnly _pdfRenderer As ChromePdfRenderer
        Private ReadOnly _pdfFormattingService As PdfFormattingService
        Private ReadOnly _environment As IWebHostEnvironment

        Public Sub New(logger As ILogger(Of InvoiceController), viewRenderer As IRazorViewRenderer, pdfRenderer As ChromePdfRenderer, pdfFormattingService As PdfFormattingService, environment As IWebHostEnvironment)
            _logger = logger
            _viewRenderer = viewRenderer
            _pdfRenderer = pdfRenderer
            _pdfFormattingService = pdfFormattingService
            _environment = environment
        End Sub

        <HttpGet>
        Public Function Index() As IActionResult
            ' Display a form or list of invoices
            Return View()
        End Function

        Private Sub ConfigurePdfRendererOptions(renderer As ChromePdfRenderer, invoice As InvoiceModel, options As PdfStylingOptions)
            ' Margins
            renderer.RenderingOptions.MarginTop = options.MarginTop
            renderer.RenderingOptions.MarginBottom = options.MarginBottom
            renderer.RenderingOptions.MarginLeft = options.MarginLeft
            renderer.RenderingOptions.MarginRight = options.MarginRight

            ' Header
            If options.UseHtmlHeader Then
                renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
                    .MaxHeight = 50,
                    .HtmlFragment = $"
                <div style='width: 100%; font-size: 12px; font-family: Arial;'>
                    <div style='float: left; width: 50%;'>
                        <img src='https://ironpdf.com/img/products/ironpdf-logo-text-dotnet.svg' height='40' />
                    </div>
                    <div style='float: right; width: 50%; text-align: right;'>
                        <strong>Invoice {invoice.InvoiceNumber}</strong><br/>
                        Generated: {DateTime.Now:yyyy-MM-dd}
                    </div>
                </div>",
                    .LoadStylesAndCSSFromMainHtmlDocument = True
                }
            Else
                renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
                    .CenterText = options.HeaderText,
                    .Font = IronSoftware.Drawing.FontTypes.Arial,
                    .FontSize = 12,
                    .DrawDividerLine = True
                }
            End If

            ' Footer
            renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
                .MaxHeight = 30,
                .HtmlFragment = "
            <div style='width: 100%; font-size: 10px; color: #666;'>
                <div style='float: left; width: 33%;'>
                    © 2025 Your Company
                </div>
                <div style='float: center; width: 33%; text-align: center;'>
                    yourwebsite.com
                </div>
                <div style='float: right; width: 33%; text-align: right;'>
                    Page {page} of {total-pages}
                </div>
            </div>"
            }

            ' Optional: Add watermark here (IronPDF supports adding after PDF is generated, so keep it as-is)
            ' Margins, paper size etc., can also be set here if needed
            renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
            renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
            renderer.RenderingOptions.PrintHtmlBackgrounds = True
        End Sub

        <HttpGet>
        Public Async Function GenerateInvoice(invoiceNumber As String) As Task(Of IActionResult)
            Dim stopwatch = Stopwatch.StartNew()
            Try
                ' Validate input
                If String.IsNullOrEmpty(invoiceNumber) Then
                    _logger.LogWarning("Invoice generation attempted without invoice number")
                    Return BadRequest("Invoice number is required")
                End If

                ' Generate sample data (in production, fetch from database)
                Dim invoice = CreateSampleInvoice(invoiceNumber)

                ' Log the generation attempt
                _logger.LogInformation($"Generating PDF for invoice {invoiceNumber}")

                ' Configure PDF rendering options
                _pdfRenderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
                _pdfRenderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
                _pdfRenderer.RenderingOptions.PrintHtmlBackgrounds = True
                _pdfRenderer.RenderingOptions.CreatePdfFormsFromHtml = False

                Dim options = New PdfStylingOptions With {
                    .MarginTop = 25,
                    .MarginBottom = 25,
                    .MarginLeft = 20,
                    .MarginRight = 20,
                    .UseHtmlHeader = True,
                    .HeaderText = $"Invoice {invoice.InvoiceNumber}",
                    .AddWatermark = False,
                    .ForcePageBreaks = False
                }

                ' Apply the styling to the renderer BEFORE rendering PDF
                ConfigurePdfRendererOptions(_pdfRenderer, invoice, options)

                ' Render the view to PDF
                Dim pdf As PdfDocument
                Try
                    pdf = _pdfRenderer.RenderRazorViewToPdf(_viewRenderer, "Views/Invoice/InvoiceTemplate.cshtml", invoice)
                Catch renderEx As Exception
                    _logger.LogError(renderEx, "Failed to render Razor view to PDF")
                    Throw New InvalidOperationException("PDF rendering failed. Please check the template.", renderEx)
                End Try

                ' Apply metadata
                pdf.MetaData.Author = "PdfGeneratorApp"
                pdf.MetaData.Title = $"Invoice {invoice.InvoiceNumber}"
                pdf.MetaData.Subject = $"Invoice for {invoice.Customer.Name}"
                pdf.MetaData.Keywords = "invoice, billing, payment"
                pdf.MetaData.CreationDate = DateTime.UtcNow
                pdf.MetaData.ModifiedDate = DateTime.UtcNow

                ' Optional: Add password protection
                ' pdf.SecuritySettings.UserPassword = "user123"
                ' pdf.SecuritySettings.OwnerPassword = "owner456"
                ' pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights

                ' Log performance metrics
                stopwatch.Stop()
                _logger.LogInformation($"PDF generated successfully for invoice {invoiceNumber} in {stopwatch.ElapsedMilliseconds}ms")

                ' Return the PDF file
                Response.Headers.Add("Content-Disposition", $"inline; filename=Invoice_{invoiceNumber}.pdf")
                Return File(pdf.BinaryData, "application/pdf", $"Invoice_{invoiceNumber}.pdf")
            Catch ex As Exception
                _logger.LogError(ex, $"Error generating PDF for invoice {invoiceNumber}")

                ' In development, return detailed error
                If _environment.IsDevelopment() Then
                    Return StatusCode(500, New With {
                        .error = "PDF generation failed",
                        .message = ex.Message,
                        .stackTrace = ex.StackTrace
                    })
                End If

                ' In production, return generic error
                Return StatusCode(500, "An error occurred while generating the PDF")
            End Try
        End Function

        Private Function CreateSampleInvoice(invoiceNumber As String) As InvoiceModel
            Return New InvoiceModel With {
                .InvoiceNumber = invoiceNumber,
                .InvoiceDate = DateTime.Now,
                .DueDate = DateTime.Now.AddDays(30),
                .Vendor = New CompanyInfo With {
                    .Name = "Tech Çözüms Inc.",
                    .Address = "123 Business Ave",
                    .City = "New York",
                    .State = "NY",
                    .ZipCode = "10001",
                    .Email = "billing@techsolutions.com",
                    .Phone = "(555) 123-4567"
                },
                .Customer = New CompanyInfo With {
                    .Name = "Acme Corporation",
                    .Address = "456 Commerce St",
                    .City = "Los Angeles",
                    .State = "CA",
                    .ZipCode = "90001",
                    .Email = "accounts@acmecorp.com",
                    .Phone = "(555) 987-6543"
                },
                .Items = New List(Of InvoiceItem) From {
                    New InvoiceItem With {
                        .Description = "Software Development Services - 40 hours",
                        .Quantity = 40,
                        .UnitPrice = 150.0D
                    },
                    New InvoiceItem With {
                        .Description = "Project Management - 10 hours",
                        .Quantity = 10,
                        .UnitPrice = 120.0D
                    },
                    New InvoiceItem With {
                        .Description = "Quality Assurance Testing",
                        .Quantity = 1,
                        .UnitPrice = 2500.0D
                    }
                },
                .TaxRate = 8.875D,
                .Notes = "Payment is due within 30 days. Late payments subject to 1.5% monthly interest.",
                .PaymentTerms = "Net 30"
            }
        End Function

    End Class

End Namespace
$vbLabelText   $csharpLabel

Kod Açıklaması

Temel ve stilize edilmiş başlıklar arasındaki kısa farkları görebilirsiniz. IronPDF ile faturanıza özelleştirilmiş HTML üstbilgileri ve altbilgileri ekleyerek onu daha da stilize edebilir ve gerçekten kendinize ait hale getirebilirsiniz.
Üstbilgi ve altbilgi ekleme hakkında daha ayrıntılı bilgi için lütfen bu
nasıl yapılır kılavuzuna bakın.

Çıktı

!C# Kullanarak ASP.NET'te PDF Oluşturma: Şekil 5 - Şekillendirilmiş PDF çıktısı

Yüksek Performanslı Toplu PDF İşleme Nasıl Uygulanır?

Yüzlerce veya binlerce PDF oluşturmanız mı gerekiyor? Belleği verimli bir şekilde yönetirken paralel işleme ile optimum performansı nasıl elde edeceğinizi öğrenin. Bunu çalışırken görmek için eksiksiz çalışma örneğimizi indirin.

Birden fazla PDF'yi verimli bir şekilde oluşturması gereken uygulamalar için async ve multithreading tekniklerini kullanan optimize edilmiş bir toplu işleme uygulaması. Bu yaklaşım, C# kullanarak ASP.NET Core'da PDF oluştururken optimum performans için Microsoft'un paralel programlama en iyi uygulamalarını takip eder:

using System.Collections.Concurrent;
using System.Diagnostics;
public class BatchPdfProcessor
{
    private readonly ChromePdfRenderer _renderer;
    private readonly ILogger<BatchPdfProcessor> _logger;
    private readonly SemaphoreSlim _semaphore;
    public BatchPdfProcessor(
        ChromePdfRenderer renderer,
        ILogger<BatchPdfProcessor> logger)
    {
        _renderer = renderer;
        _logger = logger;
        // Limit concurrent PDF generation to prevent memory exhaustion
        _semaphore = new SemaphoreSlim(Environment.ProcessorCount);
    }
    public async Task<BatchProcessingResult> ProcessBatchAsync(
        List<BatchPdfRequest> requests,
        IProgress<BatchProgressReport> progress = null)
    {
        var result = new BatchProcessingResult
        {
            StartTime = DateTime.UtcNow,
            TotalRequests = requests.Count
        };
        var successfulPdfs = new ConcurrentBag<GeneratedPdf>();
        var errors = new ConcurrentBag<ProcessingError>();
        var stopwatch = Stopwatch.StartNew();
        // Process PDFs in parallel with controlled concurrency
        var tasks = requests.Select(async (request, index) =>
        {
            await _semaphore.WaitAsync();
            try
            {
                var taskStopwatch = Stopwatch.StartNew();
                // Generate PDF
                var pdf = await GeneratePdfAsync(request);
                taskStopwatch.Stop();
                successfulPdfs.Add(new GeneratedPdf
                {
                    Id = request.Id,
                    FileName = request.FileName,
                    Data = pdf.BinaryData,
                    GenerationTime = taskStopwatch.ElapsedMilliseconds,
                    PageCount = pdf.PageCount
                });
                // Report progress
                progress?.Report(new BatchProgressReport
                {
                    ProcessedCount = successfulPdfs.Count + errors.Count,
                    TotalCount = requests.Count,
                    CurrentFile = request.FileName
                });
                _logger.LogDebug($"Generated PDF {request.Id} in {taskStopwatch.ElapsedMilliseconds}ms");
            }
            catch (İstisna ex)
            {
                errors.Add(new ProcessingError
                {
                    RequestId = request.Id,
                    FileName = request.FileName,
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                });
                _logger.LogError(ex, $"Failed to generate PDF for request {request.Id}");
            }
            finally
            {
                _semaphore.Release();
            }
        });
        await Task.WhenAll(tasks);
        stopwatch.Stop();
        // Compile results
        result.EndTime = DateTime.UtcNow;
        result.TotalProcessingTime = stopwatch.ElapsedMilliseconds;
        result.SuccessfulPdfs = successfulPdfs.ToList();
        result.Errors = errors.ToList();
        result.SuccessCount = successfulPdfs.Count;
        result.ErrorCount = errors.Count;
        result.AverageGenerationTime = successfulPdfs.Any() 
            ? successfulPdfs.Average(p => p.GenerationTime) 
            : 0;
        result.TotalPages = successfulPdfs.Sum(p => p.PageCount);
        result.TotalSizeBytes = successfulPdfs.Sum(p => p.Data.Length);
        // Log summary
        _logger.LogInformation($"Batch processing completed: {result.SuccessCount} successful, " +
                             $"{result.ErrorCount} errors, {result.TotalProcessingTime}ms total time");
        // Clean up memory after large batch
        if (requests.Count > 100)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }
        return result;
    }
    private async Task<PdfDocument> GeneratePdfAsync(BatchPdfRequest request)
    {
        return await Task.Run(() =>
        {
            // Configure renderer for this specific request
            var localRenderer = new ChromePdfRenderer();
            localRenderer.RenderingOptions.PaperSize = request.PaperSize;
            localRenderer.RenderingOptions.MarginTop = request.MarginTop;
            localRenderer.RenderingOptions.MarginBottom = request.MarginBottom;
            // Generate PDF
            var pdf = localRenderer.RenderHtmlAsPdf(request.HtmlContent);
            // Apply compression if requested
            if (request.CompressImages)
            {
                pdf.CompressImages(request.CompressionQuality);
            }
            return pdf;
        });
    }
}
public class BatchPdfRequest
{
    public string Id { get; set; }
    public string FileName { get; set; }
    public string HtmlContent { get; set; }
    public IronPdf.Rendering.PdfPaperSize PaperSize { get; set; } = IronPdf.Rendering.PdfPaperSize.A4;
    public int MarginTop { get; set; } = 25;
    public int MarginBottom { get; set; } = 25;
    public bool CompressImages { get; set; } = true;
    public int CompressionQuality { get; set; } = 80;
}
public class BatchProcessingResult
{
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public long TotalProcessingTime { get; set; }
    public int TotalRequests { get; set; }
    public int SuccessCount { get; set; }
    public int ErrorCount { get; set; }
    public double AverageGenerationTime { get; set; }
    public int TotalPages { get; set; }
    public long TotalSizeBytes { get; set; }
    public List<GeneratedPdf> SuccessfulPdfs { get; set; }
    public List<ProcessingError> Errors { get; set; }
}
public class GeneratedPdf
{
    public string Id { get; set; }
    public string FileName { get; set; }
    public byte[] Data { get; set; }
    public long GenerationTime { get; set; }
    public int PageCount { get; set; }
}
public class ProcessingError
{
    public string RequestId { get; set; }
    public string FileName { get; set; }
    public string Error { get; set; }
    public string StackTrace { get; set; }
}
public class BatchProgressReport
{
    public int ProcessedCount { get; set; }
    public int TotalCount { get; set; }
    public string CurrentFile { get; set; }
    public double PercentComplete => (double)ProcessedCount / TotalCount * 100;
}
using System.Collections.Concurrent;
using System.Diagnostics;
public class BatchPdfProcessor
{
    private readonly ChromePdfRenderer _renderer;
    private readonly ILogger<BatchPdfProcessor> _logger;
    private readonly SemaphoreSlim _semaphore;
    public BatchPdfProcessor(
        ChromePdfRenderer renderer,
        ILogger<BatchPdfProcessor> logger)
    {
        _renderer = renderer;
        _logger = logger;
        // Limit concurrent PDF generation to prevent memory exhaustion
        _semaphore = new SemaphoreSlim(Environment.ProcessorCount);
    }
    public async Task<BatchProcessingResult> ProcessBatchAsync(
        List<BatchPdfRequest> requests,
        IProgress<BatchProgressReport> progress = null)
    {
        var result = new BatchProcessingResult
        {
            StartTime = DateTime.UtcNow,
            TotalRequests = requests.Count
        };
        var successfulPdfs = new ConcurrentBag<GeneratedPdf>();
        var errors = new ConcurrentBag<ProcessingError>();
        var stopwatch = Stopwatch.StartNew();
        // Process PDFs in parallel with controlled concurrency
        var tasks = requests.Select(async (request, index) =>
        {
            await _semaphore.WaitAsync();
            try
            {
                var taskStopwatch = Stopwatch.StartNew();
                // Generate PDF
                var pdf = await GeneratePdfAsync(request);
                taskStopwatch.Stop();
                successfulPdfs.Add(new GeneratedPdf
                {
                    Id = request.Id,
                    FileName = request.FileName,
                    Data = pdf.BinaryData,
                    GenerationTime = taskStopwatch.ElapsedMilliseconds,
                    PageCount = pdf.PageCount
                });
                // Report progress
                progress?.Report(new BatchProgressReport
                {
                    ProcessedCount = successfulPdfs.Count + errors.Count,
                    TotalCount = requests.Count,
                    CurrentFile = request.FileName
                });
                _logger.LogDebug($"Generated PDF {request.Id} in {taskStopwatch.ElapsedMilliseconds}ms");
            }
            catch (İstisna ex)
            {
                errors.Add(new ProcessingError
                {
                    RequestId = request.Id,
                    FileName = request.FileName,
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                });
                _logger.LogError(ex, $"Failed to generate PDF for request {request.Id}");
            }
            finally
            {
                _semaphore.Release();
            }
        });
        await Task.WhenAll(tasks);
        stopwatch.Stop();
        // Compile results
        result.EndTime = DateTime.UtcNow;
        result.TotalProcessingTime = stopwatch.ElapsedMilliseconds;
        result.SuccessfulPdfs = successfulPdfs.ToList();
        result.Errors = errors.ToList();
        result.SuccessCount = successfulPdfs.Count;
        result.ErrorCount = errors.Count;
        result.AverageGenerationTime = successfulPdfs.Any() 
            ? successfulPdfs.Average(p => p.GenerationTime) 
            : 0;
        result.TotalPages = successfulPdfs.Sum(p => p.PageCount);
        result.TotalSizeBytes = successfulPdfs.Sum(p => p.Data.Length);
        // Log summary
        _logger.LogInformation($"Batch processing completed: {result.SuccessCount} successful, " +
                             $"{result.ErrorCount} errors, {result.TotalProcessingTime}ms total time");
        // Clean up memory after large batch
        if (requests.Count > 100)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }
        return result;
    }
    private async Task<PdfDocument> GeneratePdfAsync(BatchPdfRequest request)
    {
        return await Task.Run(() =>
        {
            // Configure renderer for this specific request
            var localRenderer = new ChromePdfRenderer();
            localRenderer.RenderingOptions.PaperSize = request.PaperSize;
            localRenderer.RenderingOptions.MarginTop = request.MarginTop;
            localRenderer.RenderingOptions.MarginBottom = request.MarginBottom;
            // Generate PDF
            var pdf = localRenderer.RenderHtmlAsPdf(request.HtmlContent);
            // Apply compression if requested
            if (request.CompressImages)
            {
                pdf.CompressImages(request.CompressionQuality);
            }
            return pdf;
        });
    }
}
public class BatchPdfRequest
{
    public string Id { get; set; }
    public string FileName { get; set; }
    public string HtmlContent { get; set; }
    public IronPdf.Rendering.PdfPaperSize PaperSize { get; set; } = IronPdf.Rendering.PdfPaperSize.A4;
    public int MarginTop { get; set; } = 25;
    public int MarginBottom { get; set; } = 25;
    public bool CompressImages { get; set; } = true;
    public int CompressionQuality { get; set; } = 80;
}
public class BatchProcessingResult
{
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public long TotalProcessingTime { get; set; }
    public int TotalRequests { get; set; }
    public int SuccessCount { get; set; }
    public int ErrorCount { get; set; }
    public double AverageGenerationTime { get; set; }
    public int TotalPages { get; set; }
    public long TotalSizeBytes { get; set; }
    public List<GeneratedPdf> SuccessfulPdfs { get; set; }
    public List<ProcessingError> Errors { get; set; }
}
public class GeneratedPdf
{
    public string Id { get; set; }
    public string FileName { get; set; }
    public byte[] Data { get; set; }
    public long GenerationTime { get; set; }
    public int PageCount { get; set; }
}
public class ProcessingError
{
    public string RequestId { get; set; }
    public string FileName { get; set; }
    public string Error { get; set; }
    public string StackTrace { get; set; }
}
public class BatchProgressReport
{
    public int ProcessedCount { get; set; }
    public int TotalCount { get; set; }
    public string CurrentFile { get; set; }
    public double PercentComplete => (double)ProcessedCount / TotalCount * 100;
}
Imports System.Collections.Concurrent
Imports System.Diagnostics

Public Class BatchPdfProcessor
    Private ReadOnly _renderer As ChromePdfRenderer
    Private ReadOnly _logger As ILogger(Of BatchPdfProcessor)
    Private ReadOnly _semaphore As SemaphoreSlim

    Public Sub New(renderer As ChromePdfRenderer, logger As ILogger(Of BatchPdfProcessor))
        _renderer = renderer
        _logger = logger
        ' Limit concurrent PDF generation to prevent memory exhaustion
        _semaphore = New SemaphoreSlim(Environment.ProcessorCount)
    End Sub

    Public Async Function ProcessBatchAsync(requests As List(Of BatchPdfRequest), Optional progress As IProgress(Of BatchProgressReport) = Nothing) As Task(Of BatchProcessingResult)
        Dim result As New BatchProcessingResult With {
            .StartTime = DateTime.UtcNow,
            .TotalRequests = requests.Count
        }
        Dim successfulPdfs As New ConcurrentBag(Of GeneratedPdf)()
        Dim errors As New ConcurrentBag(Of ProcessingError)()
        Dim stopwatch As Stopwatch = Stopwatch.StartNew()

        ' Process PDFs in parallel with controlled concurrency
        Dim tasks = requests.Select(Async Function(request, index)
                                        Await _semaphore.WaitAsync()
                                        Try
                                            Dim taskStopwatch As Stopwatch = Stopwatch.StartNew()
                                            ' Generate PDF
                                            Dim pdf = Await GeneratePdfAsync(request)
                                            taskStopwatch.Stop()
                                            successfulPdfs.Add(New GeneratedPdf With {
                                                .Id = request.Id,
                                                .FileName = request.FileName,
                                                .Data = pdf.BinaryData,
                                                .GenerationTime = taskStopwatch.ElapsedMilliseconds,
                                                .PageCount = pdf.PageCount
                                            })
                                            ' Report progress
                                            If progress IsNot Nothing Then
                                                progress.Report(New BatchProgressReport With {
                                                    .ProcessedCount = successfulPdfs.Count + errors.Count,
                                                    .TotalCount = requests.Count,
                                                    .CurrentFile = request.FileName
                                                })
                                            End If
                                            _logger.LogDebug($"Generated PDF {request.Id} in {taskStopwatch.ElapsedMilliseconds}ms")
                                        Catch ex As Exception
                                            errors.Add(New ProcessingError With {
                                                .RequestId = request.Id,
                                                .FileName = request.FileName,
                                                .Error = ex.Message,
                                                .StackTrace = ex.StackTrace
                                            })
                                            _logger.LogError(ex, $"Failed to generate PDF for request {request.Id}")
                                        Finally
                                            _semaphore.Release()
                                        End Try
                                    End Function)

        Await Task.WhenAll(tasks)
        stopwatch.Stop()

        ' Compile results
        result.EndTime = DateTime.UtcNow
        result.TotalProcessingTime = stopwatch.ElapsedMilliseconds
        result.SuccessfulPdfs = successfulPdfs.ToList()
        result.Errors = errors.ToList()
        result.SuccessCount = successfulPdfs.Count
        result.ErrorCount = errors.Count
        result.AverageGenerationTime = If(successfulPdfs.Any(), successfulPdfs.Average(Function(p) p.GenerationTime), 0)
        result.TotalPages = successfulPdfs.Sum(Function(p) p.PageCount)
        result.TotalSizeBytes = successfulPdfs.Sum(Function(p) p.Data.Length)

        ' Log summary
        _logger.LogInformation($"Batch processing completed: {result.SuccessCount} successful, {result.ErrorCount} errors, {result.TotalProcessingTime}ms total time")

        ' Clean up memory after large batch
        If requests.Count > 100 Then
            GC.Collect()
            GC.WaitForPendingFinalizers()
            GC.Collect()
        End If

        Return result
    End Function

    Private Async Function GeneratePdfAsync(request As BatchPdfRequest) As Task(Of PdfDocument)
        Return Await Task.Run(Function()
                                  ' Configure renderer for this specific request
                                  Dim localRenderer As New ChromePdfRenderer()
                                  localRenderer.RenderingOptions.PaperSize = request.PaperSize
                                  localRenderer.RenderingOptions.MarginTop = request.MarginTop
                                  localRenderer.RenderingOptions.MarginBottom = request.MarginBottom
                                  ' Generate PDF
                                  Dim pdf = localRenderer.RenderHtmlAsPdf(request.HtmlContent)
                                  ' Apply compression if requested
                                  If request.CompressImages Then
                                      pdf.CompressImages(request.CompressionQuality)
                                  End If
                                  Return pdf
                              End Function)
    End Function
End Class

Public Class BatchPdfRequest
    Public Property Id As String
    Public Property FileName As String
    Public Property HtmlContent As String
    Public Property PaperSize As IronPdf.Rendering.PdfPaperSize = IronPdf.Rendering.PdfPaperSize.A4
    Public Property MarginTop As Integer = 25
    Public Property MarginBottom As Integer = 25
    Public Property CompressImages As Boolean = True
    Public Property CompressionQuality As Integer = 80
End Class

Public Class BatchProcessingResult
    Public Property StartTime As DateTime
    Public Property EndTime As DateTime
    Public Property TotalProcessingTime As Long
    Public Property TotalRequests As Integer
    Public Property SuccessCount As Integer
    Public Property ErrorCount As Integer
    Public Property AverageGenerationTime As Double
    Public Property TotalPages As Integer
    Public Property TotalSizeBytes As Long
    Public Property SuccessfulPdfs As List(Of GeneratedPdf)
    Public Property Errors As List(Of ProcessingError)
End Class

Public Class GeneratedPdf
    Public Property Id As String
    Public Property FileName As String
    Public Property Data As Byte()
    Public Property GenerationTime As Long
    Public Property PageCount As Integer
End Class

Public Class ProcessingError
    Public Property RequestId As String
    Public Property FileName As String
    Public Property Error As String
    Public Property StackTrace As String
End Class

Public Class BatchProgressReport
    Public Property ProcessedCount As Integer
    Public Property TotalCount As Integer
    Public Property CurrentFile As String
    Public ReadOnly Property PercentComplete As Double
        Get
            Return CDbl(ProcessedCount) / TotalCount * 100
        End Get
    End Property
End Class
$vbLabelText   $csharpLabel

Gerçek Dünya Sağlık Hizmetleri Raporu Örneği

İşte HIPAA uyumlu tıbbi raporlar oluşturmak için özel bir uygulama:

public class MedicalReportGenerator
{
    private readonly ChromePdfRenderer _renderer;
    private readonly ILogger<MedicalReportGenerator> _logger;
    public MedicalReportGenerator(
        ChromePdfRenderer renderer,
        ILogger<MedicalReportGenerator> logger)
    {
        _renderer = renderer;
        _logger = logger;
    }
    public async Task<PdfDocument> GeneratePatientReport(PatientReportModel model)
    {
        var stopwatch = Stopwatch.StartNew();
        // Configure for medical document standards
        _renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
        _renderer.RenderingOptions.MarginTop = 50;
        _renderer.RenderingOptions.MarginBottom = 40;
        // HIPAA-compliant header
        _renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
        {
            Height = 45,
            HtmlFragment = $@"
                <div style='width: 100%; font-size: 10px;'>
                    <div style='float: left;'>
                        <strong>CONFIDENTIAL MEDICAL RECORD</strong><br/>
                        Patient: {model.PatientName} | MRN: {model.MedicalRecordNumber}
                    </div>
                    <div style='float: right; text-align: right;'>
                        Generated: {{date}} {{time}}<br/>
                        Provider: {model.ProviderName}
                    </div>
                </div>"
        };
        // Generate report HTML
        var html = GenerateMedicalReportHtml(model);
        // Create PDF with encryption for HIPAA compliance
        var pdf = _renderer.RenderHtmlAsPdf(html);
        // Apply 256-bit AES encryption
        pdf.SecuritySettings.UserPassword = GenerateSecurePassword();
        pdf.SecuritySettings.OwnerPassword = GenerateOwnerPassword();
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
        pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
        pdf.SecuritySettings.AllowUserFormData = false;
        pdf.SecuritySettings.AllowUserAnnotations = false;
        // Add audit metadata
        pdf.MetaData.Author = model.ProviderName;
        pdf.MetaData.Title = $"Medical Report - {model.PatientName}";
        pdf.MetaData.Keywords = "medical,confidential,hipaa";
        pdf.MetaData.CustomProperties.Add("ReportType", model.ReportType);
        pdf.MetaData.CustomProperties.Add("GeneratedBy", model.UserId);
        pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"));
        stopwatch.Stop();
        _logger.LogInformation($"Medical report generated in {stopwatch.ElapsedMilliseconds}ms for patient {model.MedicalRecordNumber}");
        return pdf;
    }
    private string GenerateMedicalReportHtml(PatientReportModel model)
    {
        // Generate comprehensive medical report HTML
        // This would typically use a Razor view in production
        return $@"
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; }}
                    .header {{ background: #f0f4f8; padding: 20px; margin-bottom: 30px; }}
                    .patient-info {{ display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }}
                    .section {{ margin-bottom: 30px; }}
                    .section h2 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
                    .vital-signs {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }}
                    .vital-box {{ background: #ecf0f1; padding: 15px; border-radius: 5px; }}
                    .medication-table {{ width: 100%; border-collapse: collapse; }}
                    .medication-table th, .medication-table td {{ border: 1px solid #ddd; padding: 10px; text-align: left; }}
                    .medication-table th {{ background: #3498db; color: white; }}
                    .alert {{ background: #e74c3c; color: white; padding: 10px; border-radius: 5px; margin-bottom: 20px; }}
                </style>
            </head>
            <body>
                <div class='header'>
                    <h1>Patient Medical Report</h1>
                    <p>Report Date: {DateTime.Now:MMMM dd, yyyy}</p>
                </div>
                {(model.HasAllergies ? "<div class='alert'>⚠ PATIENT HAS KNOWN ALLERGIES - SEE ALLERGY SECTION</div>" : "")}
                <div class='patient-info'>
                    <div>
                        <strong>Patient Name:</strong> {model.PatientName}<br/>
                        <strong>Date of Birth:</strong> {model.DateOfBirth:MM/dd/yyyy}<br/>
                        <strong>Age:</strong> {model.Age} years<br/>
                        <strong>Gender:</strong> {model.Gender}
                    </div>
                    <div>
                        <strong>MRN:</strong> {model.MedicalRecordNumber}<br/>
                        <strong>Admission Date:</strong> {model.AdmissionDate:MM/dd/yyyy}<br/>
                        <strong>Provider:</strong> {model.ProviderName}<br/>
                        <strong>Department:</strong> {model.Department}
                    </div>
                </div>
                <div class='section'>
                    <h2>Vital Signs</h2>
                    <div class='vital-signs'>
                        <div class='vital-box'>
                            <strong>Blood Pressure</strong><br/>
                            {model.BloodPressure}
                        </div>
                        <div class='vital-box'>
                            <strong>Heart Rate</strong><br/>
                            {model.HeartRate} bpm
                        </div>
                        <div class='vital-box'>
                            <strong>Temperature</strong><br/>
                            {model.Temperature}°F
                        </div>
                        <div class='vital-box'>
                            <strong>Respiratory Rate</strong><br/>
                            {model.RespiratoryRate} /min
                        </div>
                        <div class='vital-box'>
                            <strong>O2 Saturation</strong><br/>
                            {model.OxygenSaturation}%
                        </div>
                        <div class='vital-box'>
                            <strong>Weight</strong><br/>
                            {model.Weight} lbs
                        </div>
                    </div>
                </div>
                <div class='section'>
                    <h2>Current Medications</h2>
                    <table class='medication-table'>
                        <thead>
                            <tr>
                                <th>Medication</th>
                                <th>Dosage</th>
                                <th>Frequency</th>
                                <th>Route</th>
                                <th>Start Date</th>
                            </tr>
                        </thead>
                        <tbody>
                            {string.Join("", model.Medications.Select(m => $@"
                                <tr>
                                    <td>{m.Name}</td>
                                    <td>{m.Dosage}</td>
                                    <td>{m.Frequency}</td>
                                    <td>{m.Route}</td>
                                    <td>{m.StartDate:MM/dd/yyyy}</td>
                                </tr>
                            "))}
                        </tbody>
                    </table>
                </div>
                <div class='section'>
                    <h2>Clinical Notes</h2>
                    <p>{model.ClinicalNotes}</p>
                </div>
                <div class='section'>
                    <h2>Treatment Plan</h2>
                    <p>{model.TreatmentPlan}</p>
                </div>
            </body>
            </html>";
    }
    private string GenerateSecurePassword()
    {
        // Generate cryptographically secure password
        using var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
        var bytes = new byte[32];
        rng.GetBytes(bytes);
        return Convert.ToBase64String(bytes);
    }
    private string GenerateOwnerPassword()
    {
        // In production, retrieve from secure configuration
        return "SecureOwnerPassword123!";
    }
}
public class PatientReportModel
{
    public string PatientName { get; set; }
    public string MedicalRecordNumber { get; set; }
    public DateTime DateOfBirth { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public DateTime AdmissionDate { get; set; }
    public string ProviderName { get; set; }
    public string Department { get; set; }
    public string ReportType { get; set; }
    public string UserId { get; set; }
    // Vital Signs
    public string BloodPressure { get; set; }
    public int HeartRate { get; set; }
    public decimal Temperature { get; set; }
    public int RespiratoryRate { get; set; }
    public int OxygenSaturation { get; set; }
    public decimal Weight { get; set; }
    // Medical Information
    public bool HasAllergies { get; set; }
    public List<Medication> Medications { get; set; }
    public string ClinicalNotes { get; set; }
    public string TreatmentPlan { get; set; }
}
public class Medication
{
    public string Name { get; set; }
    public string Dosage { get; set; }
    public string Frequency { get; set; }
    public string Route { get; set; }
    public DateTime StartDate { get; set; }
}
public class MedicalReportGenerator
{
    private readonly ChromePdfRenderer _renderer;
    private readonly ILogger<MedicalReportGenerator> _logger;
    public MedicalReportGenerator(
        ChromePdfRenderer renderer,
        ILogger<MedicalReportGenerator> logger)
    {
        _renderer = renderer;
        _logger = logger;
    }
    public async Task<PdfDocument> GeneratePatientReport(PatientReportModel model)
    {
        var stopwatch = Stopwatch.StartNew();
        // Configure for medical document standards
        _renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
        _renderer.RenderingOptions.MarginTop = 50;
        _renderer.RenderingOptions.MarginBottom = 40;
        // HIPAA-compliant header
        _renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
        {
            Height = 45,
            HtmlFragment = $@"
                <div style='width: 100%; font-size: 10px;'>
                    <div style='float: left;'>
                        <strong>CONFIDENTIAL MEDICAL RECORD</strong><br/>
                        Patient: {model.PatientName} | MRN: {model.MedicalRecordNumber}
                    </div>
                    <div style='float: right; text-align: right;'>
                        Generated: {{date}} {{time}}<br/>
                        Provider: {model.ProviderName}
                    </div>
                </div>"
        };
        // Generate report HTML
        var html = GenerateMedicalReportHtml(model);
        // Create PDF with encryption for HIPAA compliance
        var pdf = _renderer.RenderHtmlAsPdf(html);
        // Apply 256-bit AES encryption
        pdf.SecuritySettings.UserPassword = GenerateSecurePassword();
        pdf.SecuritySettings.OwnerPassword = GenerateOwnerPassword();
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
        pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
        pdf.SecuritySettings.AllowUserFormData = false;
        pdf.SecuritySettings.AllowUserAnnotations = false;
        // Add audit metadata
        pdf.MetaData.Author = model.ProviderName;
        pdf.MetaData.Title = $"Medical Report - {model.PatientName}";
        pdf.MetaData.Keywords = "medical,confidential,hipaa";
        pdf.MetaData.CustomProperties.Add("ReportType", model.ReportType);
        pdf.MetaData.CustomProperties.Add("GeneratedBy", model.UserId);
        pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"));
        stopwatch.Stop();
        _logger.LogInformation($"Medical report generated in {stopwatch.ElapsedMilliseconds}ms for patient {model.MedicalRecordNumber}");
        return pdf;
    }
    private string GenerateMedicalReportHtml(PatientReportModel model)
    {
        // Generate comprehensive medical report HTML
        // This would typically use a Razor view in production
        return $@"
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; }}
                    .header {{ background: #f0f4f8; padding: 20px; margin-bottom: 30px; }}
                    .patient-info {{ display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }}
                    .section {{ margin-bottom: 30px; }}
                    .section h2 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
                    .vital-signs {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }}
                    .vital-box {{ background: #ecf0f1; padding: 15px; border-radius: 5px; }}
                    .medication-table {{ width: 100%; border-collapse: collapse; }}
                    .medication-table th, .medication-table td {{ border: 1px solid #ddd; padding: 10px; text-align: left; }}
                    .medication-table th {{ background: #3498db; color: white; }}
                    .alert {{ background: #e74c3c; color: white; padding: 10px; border-radius: 5px; margin-bottom: 20px; }}
                </style>
            </head>
            <body>
                <div class='header'>
                    <h1>Patient Medical Report</h1>
                    <p>Report Date: {DateTime.Now:MMMM dd, yyyy}</p>
                </div>
                {(model.HasAllergies ? "<div class='alert'>⚠ PATIENT HAS KNOWN ALLERGIES - SEE ALLERGY SECTION</div>" : "")}
                <div class='patient-info'>
                    <div>
                        <strong>Patient Name:</strong> {model.PatientName}<br/>
                        <strong>Date of Birth:</strong> {model.DateOfBirth:MM/dd/yyyy}<br/>
                        <strong>Age:</strong> {model.Age} years<br/>
                        <strong>Gender:</strong> {model.Gender}
                    </div>
                    <div>
                        <strong>MRN:</strong> {model.MedicalRecordNumber}<br/>
                        <strong>Admission Date:</strong> {model.AdmissionDate:MM/dd/yyyy}<br/>
                        <strong>Provider:</strong> {model.ProviderName}<br/>
                        <strong>Department:</strong> {model.Department}
                    </div>
                </div>
                <div class='section'>
                    <h2>Vital Signs</h2>
                    <div class='vital-signs'>
                        <div class='vital-box'>
                            <strong>Blood Pressure</strong><br/>
                            {model.BloodPressure}
                        </div>
                        <div class='vital-box'>
                            <strong>Heart Rate</strong><br/>
                            {model.HeartRate} bpm
                        </div>
                        <div class='vital-box'>
                            <strong>Temperature</strong><br/>
                            {model.Temperature}°F
                        </div>
                        <div class='vital-box'>
                            <strong>Respiratory Rate</strong><br/>
                            {model.RespiratoryRate} /min
                        </div>
                        <div class='vital-box'>
                            <strong>O2 Saturation</strong><br/>
                            {model.OxygenSaturation}%
                        </div>
                        <div class='vital-box'>
                            <strong>Weight</strong><br/>
                            {model.Weight} lbs
                        </div>
                    </div>
                </div>
                <div class='section'>
                    <h2>Current Medications</h2>
                    <table class='medication-table'>
                        <thead>
                            <tr>
                                <th>Medication</th>
                                <th>Dosage</th>
                                <th>Frequency</th>
                                <th>Route</th>
                                <th>Start Date</th>
                            </tr>
                        </thead>
                        <tbody>
                            {string.Join("", model.Medications.Select(m => $@"
                                <tr>
                                    <td>{m.Name}</td>
                                    <td>{m.Dosage}</td>
                                    <td>{m.Frequency}</td>
                                    <td>{m.Route}</td>
                                    <td>{m.StartDate:MM/dd/yyyy}</td>
                                </tr>
                            "))}
                        </tbody>
                    </table>
                </div>
                <div class='section'>
                    <h2>Clinical Notes</h2>
                    <p>{model.ClinicalNotes}</p>
                </div>
                <div class='section'>
                    <h2>Treatment Plan</h2>
                    <p>{model.TreatmentPlan}</p>
                </div>
            </body>
            </html>";
    }
    private string GenerateSecurePassword()
    {
        // Generate cryptographically secure password
        using var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
        var bytes = new byte[32];
        rng.GetBytes(bytes);
        return Convert.ToBase64String(bytes);
    }
    private string GenerateOwnerPassword()
    {
        // In production, retrieve from secure configuration
        return "SecureOwnerPassword123!";
    }
}
public class PatientReportModel
{
    public string PatientName { get; set; }
    public string MedicalRecordNumber { get; set; }
    public DateTime DateOfBirth { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public DateTime AdmissionDate { get; set; }
    public string ProviderName { get; set; }
    public string Department { get; set; }
    public string ReportType { get; set; }
    public string UserId { get; set; }
    // Vital Signs
    public string BloodPressure { get; set; }
    public int HeartRate { get; set; }
    public decimal Temperature { get; set; }
    public int RespiratoryRate { get; set; }
    public int OxygenSaturation { get; set; }
    public decimal Weight { get; set; }
    // Medical Information
    public bool HasAllergies { get; set; }
    public List<Medication> Medications { get; set; }
    public string ClinicalNotes { get; set; }
    public string TreatmentPlan { get; set; }
}
public class Medication
{
    public string Name { get; set; }
    public string Dosage { get; set; }
    public string Frequency { get; set; }
    public string Route { get; set; }
    public DateTime StartDate { get; set; }
}
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Threading.Tasks
Imports IronPdf
Imports IronPdf.Rendering
Imports Microsoft.Extensions.Logging

Public Class MedicalReportGenerator
    Private ReadOnly _renderer As ChromePdfRenderer
    Private ReadOnly _logger As ILogger(Of MedicalReportGenerator)

    Public Sub New(renderer As ChromePdfRenderer, logger As ILogger(Of MedicalReportGenerator))
        _renderer = renderer
        _logger = logger
    End Sub

    Public Async Function GeneratePatientReport(model As PatientReportModel) As Task(Of PdfDocument)
        Dim stopwatch = Stopwatch.StartNew()
        ' Configure for medical document standards
        _renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
        _renderer.RenderingOptions.MarginTop = 50
        _renderer.RenderingOptions.MarginBottom = 40
        ' HIPAA-compliant header
        _renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
            .Height = 45,
            .HtmlFragment = $"
                <div style='width: 100%; font-size: 10px;'>
                    <div style='float: left;'>
                        <strong>CONFIDENTIAL MEDICAL RECORD</strong><br/>
                        Patient: {model.PatientName} | MRN: {model.MedicalRecordNumber}
                    </div>
                    <div style='float: right; text-align: right;'>
                        Generated: {{date}} {{time}}<br/>
                        Provider: {model.ProviderName}
                    </div>
                </div>"
        }
        ' Generate report HTML
        Dim html = GenerateMedicalReportHtml(model)
        ' Create PDF with encryption for HIPAA compliance
        Dim pdf = _renderer.RenderHtmlAsPdf(html)
        ' Apply 256-bit AES encryption
        pdf.SecuritySettings.UserPassword = GenerateSecurePassword()
        pdf.SecuritySettings.OwnerPassword = GenerateOwnerPassword()
        pdf.SecuritySettings.AllowUserCopyPasteContent = False
        pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
        pdf.SecuritySettings.AllowUserFormData = False
        pdf.SecuritySettings.AllowUserAnnotations = False
        ' Add audit metadata
        pdf.MetaData.Author = model.ProviderName
        pdf.MetaData.Title = $"Medical Report - {model.PatientName}"
        pdf.MetaData.Keywords = "medical,confidential,hipaa"
        pdf.MetaData.CustomProperties.Add("ReportType", model.ReportType)
        pdf.MetaData.CustomProperties.Add("GeneratedBy", model.UserId)
        pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"))
        stopwatch.Stop()
        _logger.LogInformation($"Medical report generated in {stopwatch.ElapsedMilliseconds}ms for patient {model.MedicalRecordNumber}")
        Return pdf
    End Function

    Private Function GenerateMedicalReportHtml(model As PatientReportModel) As String
        ' Generate comprehensive medical report HTML
        ' This would typically use a Razor view in production
        Return $"
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; }}
                    .header {{ background: #f0f4f8; padding: 20px; margin-bottom: 30px; }}
                    .patient-info {{ display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }}
                    .section {{ margin-bottom: 30px; }}
                    .section h2 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
                    .vital-signs {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }}
                    .vital-box {{ background: #ecf0f1; padding: 15px; border-radius: 5px; }}
                    .medication-table {{ width: 100%; border-collapse: collapse; }}
                    .medication-table th, .medication-table td {{ border: 1px solid #ddd; padding: 10px; text-align: left; }}
                    .medication-table th {{ background: #3498db; color: white; }}
                    .alert {{ background: #e74c3c; color: white; padding: 10px; border-radius: 5px; margin-bottom: 20px; }}
                </style>
            </head>
            <body>
                <div class='header'>
                    <h1>Patient Medical Report</h1>
                    <p>Report Date: {DateTime.Now:MMMM dd, yyyy}</p>
                </div>
                {(If(model.HasAllergies, "<div class='alert'>⚠ PATIENT HAS KNOWN ALLERGIES - SEE ALLERGY SECTION</div>", ""))}
                <div class='patient-info'>
                    <div>
                        <strong>Patient Name:</strong> {model.PatientName}<br/>
                        <strong>Date of Birth:</strong> {model.DateOfBirth:MM/dd/yyyy}<br/>
                        <strong>Age:</strong> {model.Age} years<br/>
                        <strong>Gender:</strong> {model.Gender}
                    </div>
                    <div>
                        <strong>MRN:</strong> {model.MedicalRecordNumber}<br/>
                        <strong>Admission Date:</strong> {model.AdmissionDate:MM/dd/yyyy}<br/>
                        <strong>Provider:</strong> {model.ProviderName}<br/>
                        <strong>Department:</strong> {model.Department}
                    </div>
                </div>
                <div class='section'>
                    <h2>Vital Signs</h2>
                    <div class='vital-signs'>
                        <div class='vital-box'>
                            <strong>Blood Pressure</strong><br/>
                            {model.BloodPressure}
                        </div>
                        <div class='vital-box'>
                            <strong>Heart Rate</strong><br/>
                            {model.HeartRate} bpm
                        </div>
                        <div class='vital-box'>
                            <strong>Temperature</strong><br/>
                            {model.Temperature}°F
                        </div>
                        <div class='vital-box'>
                            <strong>Respiratory Rate</strong><br/>
                            {model.RespiratoryRate} /min
                        </div>
                        <div class='vital-box'>
                            <strong>O2 Saturation</strong><br/>
                            {model.OxygenSaturation}%
                        </div>
                        <div class='vital-box'>
                            <strong>Weight</strong><br/>
                            {model.Weight} lbs
                        </div>
                    </div>
                </div>
                <div class='section'>
                    <h2>Current Medications</h2>
                    <table class='medication-table'>
                        <thead>
                            <tr>
                                <th>Medication</th>
                                <th>Dosage</th>
                                <th>Frequency</th>
                                <th>Route</th>
                                <th>Start Date</th>
                            </tr>
                        </thead>
                        <tbody>
                            {String.Join("", model.Medications.Select(Function(m) $"
                                <tr>
                                    <td>{m.Name}</td>
                                    <td>{m.Dosage}</td>
                                    <td>{m.Frequency}</td>
                                    <td>{m.Route}</td>
                                    <td>{m.StartDate:MM/dd/yyyy}</td>
                                </tr>
                            "))}
                        </tbody>
                    </table>
                </div>
                <div class='section'>
                    <h2>Clinical Notes</h2>
                    <p>{model.ClinicalNotes}</p>
                </div>
                <div class='section'>
                    <h2>Treatment Plan</h2>
                    <p>{model.TreatmentPlan}</p>
                </div>
            </body>
            </html>"
    End Function

    Private Function GenerateSecurePassword() As String
        ' Generate cryptographically secure password
        Using rng = System.Security.Cryptography.RandomNumberGenerator.Create()
            Dim bytes = New Byte(31) {}
            rng.GetBytes(bytes)
            Return Convert.ToBase64String(bytes)
        End Using
    End Function

    Private Function GenerateOwnerPassword() As String
        ' In production, retrieve from secure configuration
        Return "SecureOwnerPassword123!"
    End Function
End Class

Public Class PatientReportModel
    Public Property PatientName As String
    Public Property MedicalRecordNumber As String
    Public Property DateOfBirth As DateTime
    Public Property Age As Integer
    Public Property Gender As String
    Public Property AdmissionDate As DateTime
    Public Property ProviderName As String
    Public Property Department As String
    Public Property ReportType As String
    Public Property UserId As String
    ' Vital Signs
    Public Property BloodPressure As String
    Public Property HeartRate As Integer
    Public Property Temperature As Decimal
    Public Property RespiratoryRate As Integer
    Public Property OxygenSaturation As Integer
    Public Property Weight As Decimal
    ' Medical Information
    Public Property HasAllergies As Boolean
    Public Property Medications As List(Of Medication)
    Public Property ClinicalNotes As String
    Public Property TreatmentPlan As String
End Class

Public Class Medication
    Public Property Name As String
    Public Property Dosage As String
    Public Property Frequency As String
    Public Property Route As String
    Public Property StartDate As DateTime
End Class
$vbLabelText   $csharpLabel

Güvenlikle İlgili Hususlar

Üretim ortamlarında PDF oluştururken veya hassas bilgilerle çalışırken güvenlik çok önemlidir. IronPDF çeşitli güvenlik özellikleri sağlar:

Güvenlik Ayarlarının Uygulanması

using System.Text.RegularExpressions;
namespace PdfGeneratorApp.Utilities
{
    public static class PdfSecurityHelper
    {
        public static void ApplySecuritySettings(PdfDocument pdf, SecurityLevel level)
        {
            switch (level)
            {
                case SecurityLevel.Low:
                    // Basic protection
                    pdf.SecuritySettings.AllowUserCopyPasteContent = true;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                    break;
                case SecurityLevel.Medium:
                    // Restricted copying
                    pdf.SecuritySettings.UserPassword = GeneratePassword(8);
                    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.PrintLowQuality;
                    break;
                case SecurityLevel.High:
                    // Maximum security
                    pdf.SecuritySettings.UserPassword = GeneratePassword(16);
                    pdf.SecuritySettings.OwnerPassword = GeneratePassword(16);
                    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
                    pdf.SecuritySettings.AllowUserAnnotations = false;
                    pdf.SecuritySettings.AllowUserFormData = false;
                    break;
            }
        }
    public enum SecurityLevel
    {
        Low,
        Medium,
        High
    }
}
using System.Text.RegularExpressions;
namespace PdfGeneratorApp.Utilities
{
    public static class PdfSecurityHelper
    {
        public static void ApplySecuritySettings(PdfDocument pdf, SecurityLevel level)
        {
            switch (level)
            {
                case SecurityLevel.Low:
                    // Basic protection
                    pdf.SecuritySettings.AllowUserCopyPasteContent = true;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
                    break;
                case SecurityLevel.Medium:
                    // Restricted copying
                    pdf.SecuritySettings.UserPassword = GeneratePassword(8);
                    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.PrintLowQuality;
                    break;
                case SecurityLevel.High:
                    // Maximum security
                    pdf.SecuritySettings.UserPassword = GeneratePassword(16);
                    pdf.SecuritySettings.OwnerPassword = GeneratePassword(16);
                    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
                    pdf.SecuritySettings.AllowUserAnnotations = false;
                    pdf.SecuritySettings.AllowUserFormData = false;
                    break;
            }
        }
    public enum SecurityLevel
    {
        Low,
        Medium,
        High
    }
}
Imports System.Text.RegularExpressions

Namespace PdfGeneratorApp.Utilities

    Public Module PdfSecurityHelper

        Public Sub ApplySecuritySettings(pdf As PdfDocument, level As SecurityLevel)
            Select Case level
                Case SecurityLevel.Low
                    ' Basic protection
                    pdf.SecuritySettings.AllowUserCopyPasteContent = True
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights
                Case SecurityLevel.Medium
                    ' Restricted copying
                    pdf.SecuritySettings.UserPassword = GeneratePassword(8)
                    pdf.SecuritySettings.AllowUserCopyPasteContent = False
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.PrintLowQuality
                Case SecurityLevel.High
                    ' Maximum security
                    pdf.SecuritySettings.UserPassword = GeneratePassword(16)
                    pdf.SecuritySettings.OwnerPassword = GeneratePassword(16)
                    pdf.SecuritySettings.AllowUserCopyPasteContent = False
                    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint
                    pdf.SecuritySettings.AllowUserAnnotations = False
                    pdf.SecuritySettings.AllowUserFormData = False
            End Select
        End Sub

        Public Enum SecurityLevel
            Low
            Medium
            High
        End Enum

    End Module

End Namespace
$vbLabelText   $csharpLabel

Yukarıdaki yardımcı sınıfta, PDF için farklı güvenlik seçenekleri ayarlamak üzere SecurityLevel enum'unu kullanıyoruz. Örneğin, düşük @@--CODE-3--@ temel koruma uygular ancak yine de @@--CODE-4--@ ve @@--CODE-5--@ özelliğini true olarak ayarlayarak PDF'den kopyalama ve yapıştırmaya izin verir. Bu ayarlar, IronPDF ile PDF sınıfı özellikleri ayarlanarak etkinleştirilir. Güvenlik özelliklerinin ve seçeneklerinin tam listesi için lütfen how-to kılavuzuna bakın.

Hata İşleme ve Sorun Giderme

ASP.NET Core'da PDF oluşturmaya yönelik yaygın sorunlar ve bunların çözümleri geliştirici topluluğunda kapsamlı bir şekilde tartışılmıştır. İşte en sık karşılaşılan zorluklar için kanıtlanmış çözümler:

Bellek Yönetimi

handling memory leaks in IronPDF hakkında ayrıntılı rehberlik için aşağıdaki modeli uygulayın:

public class PdfMemoryManager : IDisposable
{
    private readonly List<PdfDocument> _openDocuments = new();
    private readonly ILogger<PdfMemoryManager> _logger;
    private bool _disposed;
    public PdfMemoryManager(ILogger<PdfMemoryManager> logger)
    {
        _logger = logger;
    }
    public PdfDocument CreateDocument(ChromePdfRenderer renderer, string html)
    {
        try
        {
            var pdf = renderer.RenderHtmlAsPdf(html);
            _openDocuments.Add(pdf);
            return pdf;
        }
        catch (OutOfMemoryİstisna ex)
        {
            _logger.LogError(ex, "Out of memory while generating PDF");
            // Force garbage collection
            CleanupMemory();
            // Retry with reduced quality
            renderer.RenderingOptions.JpegQuality = 50;
            var pdf = renderer.RenderHtmlAsPdf(html);
            _openDocuments.Add(pdf);
            return pdf;
        }
    }
    private void CleanupMemory()
    {
        // Dispose all open documents
        foreach (var doc in _openDocuments)
        {
            doc?.Dispose();
        }
        _openDocuments.Clear();
        // Force garbage collection
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        _logger.LogInformation("Memory cleanup performed");
    }
    public void Dispose()
    {
        if (!_disposed)
        {
            CleanupMemory();
            _disposed = true;
        }
    }
}
public class PdfMemoryManager : IDisposable
{
    private readonly List<PdfDocument> _openDocuments = new();
    private readonly ILogger<PdfMemoryManager> _logger;
    private bool _disposed;
    public PdfMemoryManager(ILogger<PdfMemoryManager> logger)
    {
        _logger = logger;
    }
    public PdfDocument CreateDocument(ChromePdfRenderer renderer, string html)
    {
        try
        {
            var pdf = renderer.RenderHtmlAsPdf(html);
            _openDocuments.Add(pdf);
            return pdf;
        }
        catch (OutOfMemoryİstisna ex)
        {
            _logger.LogError(ex, "Out of memory while generating PDF");
            // Force garbage collection
            CleanupMemory();
            // Retry with reduced quality
            renderer.RenderingOptions.JpegQuality = 50;
            var pdf = renderer.RenderHtmlAsPdf(html);
            _openDocuments.Add(pdf);
            return pdf;
        }
    }
    private void CleanupMemory()
    {
        // Dispose all open documents
        foreach (var doc in _openDocuments)
        {
            doc?.Dispose();
        }
        _openDocuments.Clear();
        // Force garbage collection
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        _logger.LogInformation("Memory cleanup performed");
    }
    public void Dispose()
    {
        if (!_disposed)
        {
            CleanupMemory();
            _disposed = true;
        }
    }
}
Imports System
Imports System.Collections.Generic
Imports Microsoft.Extensions.Logging

Public Class PdfMemoryManager
    Implements IDisposable

    Private ReadOnly _openDocuments As New List(Of PdfDocument)()
    Private ReadOnly _logger As ILogger(Of PdfMemoryManager)
    Private _disposed As Boolean

    Public Sub New(logger As ILogger(Of PdfMemoryManager))
        _logger = logger
    End Sub

    Public Function CreateDocument(renderer As ChromePdfRenderer, html As String) As PdfDocument
        Try
            Dim pdf = renderer.RenderHtmlAsPdf(html)
            _openDocuments.Add(pdf)
            Return pdf
        Catch ex As OutOfMemoryİstisna
            _logger.LogError(ex, "Out of memory while generating PDF")
            ' Force garbage collection
            CleanupMemory()
            ' Retry with reduced quality
            renderer.RenderingOptions.JpegQuality = 50
            Dim pdf = renderer.RenderHtmlAsPdf(html)
            _openDocuments.Add(pdf)
            Return pdf
        End Try
    End Function

    Private Sub CleanupMemory()
        ' Dispose all open documents
        For Each doc In _openDocuments
            doc?.Dispose()
        Next
        _openDocuments.Clear()
        ' Force garbage collection
        GC.Collect()
        GC.WaitForPendingFinalizers()
        GC.Collect()
        _logger.LogInformation("Memory cleanup performed")
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        If Not _disposed Then
            CleanupMemory()
            _disposed = True
        End If
    End Sub
End Class
$vbLabelText   $csharpLabel

Font Oluşturma Sorunları

public class FontTroubleshooter
{
    public static void EnsureFontsAvailable(ChromePdfRenderer renderer)
    {
        // Embed fonts in the PDF
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
        // Use web-safe fonts as fallback
        var fontFallback = @"
            <style>
                body {
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                }
                @font-face {
                    font-family: 'CustomFont';
                    src: url('data:font/woff2;base64,YOUR_BASE64_FONT_HERE') format('woff2');
                }
            </style>";
        // Add to HTML head
        renderer.RenderingOptions.CustomCssUrl = "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap";
    }
}
public class FontTroubleshooter
{
    public static void EnsureFontsAvailable(ChromePdfRenderer renderer)
    {
        // Embed fonts in the PDF
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
        // Use web-safe fonts as fallback
        var fontFallback = @"
            <style>
                body {
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                }
                @font-face {
                    font-family: 'CustomFont';
                    src: url('data:font/woff2;base64,YOUR_BASE64_FONT_HERE') format('woff2');
                }
            </style>";
        // Add to HTML head
        renderer.RenderingOptions.CustomCssUrl = "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap";
    }
}
Public Class FontTroubleshooter
    Public Shared Sub EnsureFontsAvailable(renderer As ChromePdfRenderer)
        ' Embed fonts in the PDF
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
        ' Use web-safe fonts as fallback
        Dim fontFallback As String = "
            <style>
                body {
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                }
                @font-face {
                    font-family: 'CustomFont';
                    src: url('data:font/woff2;base64,YOUR_BASE64_FONT_HERE') format('woff2');
                }
            </style>"
        ' Add to HTML head
        renderer.RenderingOptions.CustomCssUrl = "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap"
    End Sub
End Class
$vbLabelText   $csharpLabel

Yaygın İstisnalar ve Çözümleri

İstisna

Çünkü

Çözüm

IronPdf.İstisnas.IronPdfNativeİstisna

Chrome motoru başlatma başarısız oldu

Visual C++ Yeniden Dağıtılabilirlerinin yüklü olduğundan emin olun

System.UnauthorizedAccessİstisna

Yetersiz izinler

Temp klasörüne yazma erişimi verin

System.Timeoutİstisna

JavaScript çok uzun sürüyor

RenderDelay'i artırın veya JavaScript'i devre dışı bırakın

System.OutOfMemoryİstisna

Büyük PDF veya toplu işleme

Sayfalandırma uygulayın veya görüntü kalitesini düşürün

IronPdf.İstisnas.IronPdfLicensingİstisna

Geçersiz veya süresi dolmuş lisans

Yapılandırmada lisans anahtarını doğrulayın

Hata Ayıklama İpuçları

IronPDF ile, herhangi bir girdi ve çıktıyı aramak ve doğrulamak için uygulamanız tarafından çalıştırılan tüm işlemleri kolayca hata ayıklayabilir ve günlüğe kaydedebilirsiniz. Günlük kaydını etkinleştirmek için `EnableDebugging` özelliğini true olarak ayarlayın ve LogFilePath özelliğine bir değer atayarak günlük için bir dosya yolu belirtin. İşte bunun nasıl yapılacağını gösteren hızlı bir kod parçacığı.

public class PdfDebugger
{
    private readonly ILogger<PdfDebugger> _logger;
    public PdfDebugger(ILogger<PdfDebugger> logger)
    {
        _logger = logger;
    }
    public void EnableDebugging(ChromePdfRenderer renderer)
    {
        // Enable detailed logging
        IronPdf.Logging.Logger.EnableDebugging = true;
        IronPdf.Logging.Logger.LogFilePath = "IronPdf.log";
        IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;
        // Log rendering settings
        _logger.LogDebug($"Paper Size: {renderer.RenderingOptions.PaperSize}");
        _logger.LogDebug($"Margins: T{renderer.RenderingOptions.MarginTop} " +
                         $"B{renderer.RenderingOptions.MarginBottom} " +
                         $"L{renderer.RenderingOptions.MarginLeft} " +
                         $"R{renderer.RenderingOptions.MarginRight}");
        _logger.LogDebug($"JavaScript Enabled: {renderer.RenderingOptions.EnableJavaScript}");
        _logger.LogDebug($"Render Delay: {renderer.RenderingOptions.RenderDelay}ms");
    }
    public void SaveDebugHtml(string html, string fileName)
    {
        // Save HTML for inspection
        var debugPath = Path.Combine("debug", $"{fileName}_{DateTime.Now:yyyyMMdd_HHmmss}.html");
        Directory.CreateDirectory("debug");
        File.WriteAllText(debugPath, html);
        _logger.LogDebug($"Debug HTML saved to: {debugPath}");
    }
}
public class PdfDebugger
{
    private readonly ILogger<PdfDebugger> _logger;
    public PdfDebugger(ILogger<PdfDebugger> logger)
    {
        _logger = logger;
    }
    public void EnableDebugging(ChromePdfRenderer renderer)
    {
        // Enable detailed logging
        IronPdf.Logging.Logger.EnableDebugging = true;
        IronPdf.Logging.Logger.LogFilePath = "IronPdf.log";
        IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;
        // Log rendering settings
        _logger.LogDebug($"Paper Size: {renderer.RenderingOptions.PaperSize}");
        _logger.LogDebug($"Margins: T{renderer.RenderingOptions.MarginTop} " +
                         $"B{renderer.RenderingOptions.MarginBottom} " +
                         $"L{renderer.RenderingOptions.MarginLeft} " +
                         $"R{renderer.RenderingOptions.MarginRight}");
        _logger.LogDebug($"JavaScript Enabled: {renderer.RenderingOptions.EnableJavaScript}");
        _logger.LogDebug($"Render Delay: {renderer.RenderingOptions.RenderDelay}ms");
    }
    public void SaveDebugHtml(string html, string fileName)
    {
        // Save HTML for inspection
        var debugPath = Path.Combine("debug", $"{fileName}_{DateTime.Now:yyyyMMdd_HHmmss}.html");
        Directory.CreateDirectory("debug");
        File.WriteAllText(debugPath, html);
        _logger.LogDebug($"Debug HTML saved to: {debugPath}");
    }
}
Imports System
Imports System.IO
Imports Microsoft.Extensions.Logging

Public Class PdfDebugger
    Private ReadOnly _logger As ILogger(Of PdfDebugger)

    Public Sub New(logger As ILogger(Of PdfDebugger))
        _logger = logger
    End Sub

    Public Sub EnableDebugging(renderer As ChromePdfRenderer)
        ' Enable detailed logging
        IronPdf.Logging.Logger.EnableDebugging = True
        IronPdf.Logging.Logger.LogFilePath = "IronPdf.log"
        IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All
        ' Log rendering settings
        _logger.LogDebug($"Paper Size: {renderer.RenderingOptions.PaperSize}")
        _logger.LogDebug($"Margins: T{renderer.RenderingOptions.MarginTop} " &
                         $"B{renderer.RenderingOptions.MarginBottom} " &
                         $"L{renderer.RenderingOptions.MarginLeft} " &
                         $"R{renderer.RenderingOptions.MarginRight}")
        _logger.LogDebug($"JavaScript Enabled: {renderer.RenderingOptions.EnableJavaScript}")
        _logger.LogDebug($"Render Delay: {renderer.RenderingOptions.RenderDelay}ms")
    End Sub

    Public Sub SaveDebugHtml(html As String, fileName As String)
        ' Save HTML for inspection
        Dim debugPath = Path.Combine("debug", $"{fileName}_{DateTime.Now:yyyyMMdd_HHmmss}.html")
        Directory.CreateDirectory("debug")
        File.WriteAllText(debugPath, html)
        _logger.LogDebug($"Debug HTML saved to: {debugPath}")
    End Sub
End Class
$vbLabelText   $csharpLabel

Local Deployment Best Practices

IIS Yapılandırması

IIS'ye dağıtmak için uygun yapılandırmayı sağlayın:


<configuration>
  <system.webServer>

    <applicationPool>
      <processModel enable32BitAppOnWin64="false" />
    </applicationPool>

    <httpRuntime executionTimeout="300" maxRequestLength="51200" />

    <system.web>
      <compilation tempDirectory="~/App_Data/Temp/" />
    </system.web>
  </system.webServer>
</configuration>

<configuration>
  <system.webServer>

    <applicationPool>
      <processModel enable32BitAppOnWin64="false" />
    </applicationPool>

    <httpRuntime executionTimeout="300" maxRequestLength="51200" />

    <system.web>
      <compilation tempDirectory="~/App_Data/Temp/" />
    </system.web>
  </system.webServer>
</configuration>
XML

Gerekli Bağımlılıklar

Bu bileşenlerin dağıtım sunucunuzda yüklü olduğundan emin olun:

  1. .NET Runtime - Sürüm 6.0 veya üstü
  2. Visual C++ Yeniden Dağıtılabilir - 2015-2022 (x64)
  3. Windows Server - 2012 R2 veya üstü önerilir

Dosya Sistemi İzinleri

# Grant IIS_IUSRS write access to temp folder
icacls "C:\inetpub\wwwroot\YourApp\App_Data\Temp" /grant "IIS_IUSRS:(OI)(CI)M" /T
# Grant access to IronPDF cache folder
icacls "C:\Windows\Temp\IronPdf" /grant "IIS_IUSRS:(OI)(CI)M" /T
# Grant IIS_IUSRS write access to temp folder
icacls "C:\inetpub\wwwroot\YourApp\App_Data\Temp" /grant "IIS_IUSRS:(OI)(CI)M" /T
# Grant access to IronPDF cache folder
icacls "C:\Windows\Temp\IronPdf" /grant "IIS_IUSRS:(OI)(CI)M" /T
SHELL

Performans Ayarlama

// Startup.cs or Program.cs
public void ConfigureServices(IServiceCollection services)
{
    // Configure IronPDF for production
    services.AddSingleton<ChromePdfRenderer>(provider =>
    {
        var renderer = new ChromePdfRenderer();
        // Production optimizations
        renderer.RenderingOptions.RenderDelay = 50; // Minimize delay
        renderer.RenderingOptions.Timeout = 120; // 2 minutes max
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
        // Enable caching for static resources
        Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled;
        Installation.LinuxAndDockerDependenciesAutoConfig = false;
        return renderer;
    });
    // Configure memory cache for generated PDFs
    services.AddMemoryCache(options =>
    {
        options.SizeLimit = 100_000_000; // 100 MB cache
    });
}
// Startup.cs or Program.cs
public void ConfigureServices(IServiceCollection services)
{
    // Configure IronPDF for production
    services.AddSingleton<ChromePdfRenderer>(provider =>
    {
        var renderer = new ChromePdfRenderer();
        // Production optimizations
        renderer.RenderingOptions.RenderDelay = 50; // Minimize delay
        renderer.RenderingOptions.Timeout = 120; // 2 minutes max
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
        // Enable caching for static resources
        Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled;
        Installation.LinuxAndDockerDependenciesAutoConfig = false;
        return renderer;
    });
    // Configure memory cache for generated PDFs
    services.AddMemoryCache(options =>
    {
        options.SizeLimit = 100_000_000; // 100 MB cache
    });
}
Imports IronPdf
Imports Microsoft.Extensions.DependencyInjection

Public Sub ConfigureServices(services As IServiceCollection)
    ' Configure IronPDF for production
    services.AddSingleton(Of ChromePdfRenderer)(Function(provider)
                                                    Dim renderer = New ChromePdfRenderer()
                                                    ' Production optimizations
                                                    renderer.RenderingOptions.RenderDelay = 50 ' Minimize delay
                                                    renderer.RenderingOptions.Timeout = 120 ' 2 minutes max
                                                    renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
                                                    ' Enable caching for static resources
                                                    Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled
                                                    Installation.LinuxAndDockerDependenciesAutoConfig = False
                                                    Return renderer
                                                End Function)
    ' Configure memory cache for generated PDFs
    services.AddMemoryCache(Sub(options)
                                options.SizeLimit = 100000000 ' 100 MB cache
                            End Sub)
End Sub
$vbLabelText   $csharpLabel

En İyi Uygulamalar Özeti

  1. Bellek sızıntılarını önlemek için PdfDocument nesnelerini her zaman atın
  2. Daha iyi performans için ChromePdfRenderer örneklerini yeniden kullanın
  3. Detaylı günlük kaydı ile uygun hata işlemeyi uygulayın
  4. PDF oluşturmadan önce tüm kullanıcı girdilerini temizleyin
  5. Daha iyi ölçeklenebilirlik için async/await kalıplarını kullanın
  6. JavaScript işleme için uygun zaman aşımlarını yapılandırma
  7. Dosya boyutunu küçültmek için görüntüleri sıkıştırın
  8. İçerik statik olduğunda oluşturulan PDF'leri önbelleğe alın
  9. Toplu işlem sırasında bellek kullanımını izleme
  10. Dağıtımdan önce üretim benzeri veri hacimleriyle test edin

ASP.NET Uygulamanızı Bugün Dönüştürün

Artık IronPDF ile C# kullanarak ASP.NET Core'da PDF oluşturma konusunda kapsamlı bir anlayışa sahipsiniz. Temel Razor görünüm dönüştürmeden performans optimizasyonlu gelişmiş toplu işlemeye kadar, Chrome'da gördüklerinizle birebir eşleşen Professional PDF üretimi uygulamak için donanımlısınız.

Kilidini açtığınız önemli başarılar:

  • hTML sayfalarından, web sayfalarından vb. bir PDF oluşturduğunuzda biçimlendirme sürprizlerini ortadan kaldıran IronPDF'nin Chrome motorunu kullanarak Piksel mükemmelliğinde işleme.
  • Üretime hazır şablonlar ile Razor görünümleri, tanıdık, bakımı yapılabilir PDF oluşturma sağlar
  • Enterprise seviyesi hata işleme ve geniş ölçekte güvenilir çalışma için bellek yönetimi
  • Paralel oluşturma ile optimize edilmiş toplu işleme, binlerce belgeyi işleme
  • Professional güvenlik özellikleri hassas belgeleri 256 bit şifreleme ile korur

Professional PDF'ler Oluşturmaya Hemen Başlayın

Şimdi IronPDF ile başlayın.
green arrow pointer

ASP.NET Core uygulamanızda PDF oluşturmaya hazır mısınız? IronPDF'nin ücretsiz deneme sürümünü hemen indirin ve 30 gün boyunca filigran veya sınırlama olmadan profesyonel PDF oluşturmanın gücünü deneyimleyin. kapsamlı belgeler, yanıt veren mühendislik desteği ve 30 günlük para iade garantisi ile üretime hazır PDF çözümlerini güvenle oluşturabilirsiniz.

Yolculuğunuz için Temel Kaynaklar

ASP.NET Core uygulamalarınızı beklendiği gibi çalışan kurumsal düzeyde PDF oluşturma ile dönüştürün ve IronPDF ile oluşturmaya bugün başlayın!

Sıkça Sorulan Sorular

IronPDF'nin ASP.NET uygulamalarindaki ana kullanım amaci nedir?

IronPDF, esas olarak PDF belgelerini oluşturmak, düzenlemek ve içerik çıkarmak için kullanilir, bu, ASP.NET uygulamalarinda faturalar, raporlar, sertifikalar veya biletler oluşturmak için temel bir aractir.

IronPDF piksel mükemmel PDF render ile nasıl sağlar?

IronPDF, HTML, resimler veya diğer belge formatlarini yüksek kaliteli PDF'lere doğru bir şekilde dönüştüren ileri düzey işlemler ve kurumsal özellikler sunarak piksel yogunlukta işlemler yapar.

IronPDF, ASP.NET Core uygulamalari ile entegre edilebilir mi?

Evet, IronPDF, geliştiricilere çeşitli PDF gorevlerini etkin bir şekilde yönetmek için güçlü bir kütüphane sunarak ASP.NET Core uygulamalari ile sorunsuz bir şekilde entegre edilebilir.

PDF oluşturma için IronPDF'in faydaları nelerdir?

IronPDF'nin PDF oluşturma için kullanilmasi, kullanımin kolayligi, yüksek kaliteli işlemler, karmaşık belge özellikleri için destek ve uygulamalariniz icinde PDF gorevlerini otomatiklestirme yetenegi gibi faydalar sunar.

IronPDF mevcut PDF belgelerini düzenlemeyi destekliyor mu?

Evet, IronPDF, geliştiricilerin icerigi değiştirmesine, notlar eklemesine ve PDF metadatalarini programli olarak güncellemesine olanak tanir, mevcut PDF belgelerini düzenlemeyi destekler.

IronPDF kurumsal düzeyde PDF belgeleri oluşturmak için uygun mudur?

IronPDF, karmaşık belge yapilari ve şifreleme ile dijital imzalar gibi güvenlik özelliklerini destekleyen kapsamli özellikleri dolayisiyla kurumsal düzeyde PDF belgeleri oluşturmak için idealdir.

IronPDF hangi dosya formatlarini PDF'ye dönüştürebilir?

IronPDF, HTML, resimler ve diğer belge türleri dahil olmak uzere çeşitli dosya formatlarini PDF'ye dönüştürebilir, farkli veri kaynaklariyla esneklik ve uyumluluk saglar.

IronPDF'nin PDF içerik çıkartma işlemleri nasıl işleniyor?

IronPDF, metin, resimler ve metadata çıkartma için API'ler saglayarak PDF içerik çıkarma işlemlerini yönetir, boylece PDF belgelerinden veri almayi ve yönetmeyi kolaylastirir.

IronPDF PDF belge is akislarini otomatiklestirmek için kullanilabilir mi?

Evet, IronPDF web uygulamalarinda PDF dosyalarinin toplu olarak oluşturulmasi, dönüştürulmesi ve dağıtilmasi gibi süreçleri hizlandirarak PDF belge is akislarini otomatiklestirmek için kullanilabilir.

IronPDF geliştiriciler için ne tür destekler sunuyor?

IronPDF, kapsamli dokümantasyon, örnek kod ve entegrasyon ve sorun gidermek için destek saglayan duyarlı musterı hizmetleri sunarak geliştiriciler için genis destek sunar.

IronPDF hemen .NET 10'u destekliyor mu?

IronPDF, .NET 10 için on-sürüm desteği saglar ve Kasım 2025'te beklenen .NET 10 sürümüne suan uyumludur. Geliştiriciler IronPDF'yi .NET 10 projelerinde herhangi bir özel konfigürasyon gerektirmeden kullanabilir.

Curtis Chau
Teknik Yazar

Curtis Chau, Bilgisayar Bilimleri alanında lisans derecesine sahiptir (Carleton Üniversitesi) ve Node.js, TypeScript, JavaScript ve React konularında uzmanlaşmış ön uç geliştirme üzerine uzmanlaşmıştır. Kullanıcı dostu ve estetik açıdan hoş arayüzler tasarlamaya tutkuyla bağlı olan Curtis, modern çerç...

Daha Fazlasını Oku

Iron Destek Ekibi

Haftanın 5 günü, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara