IRONPDF 사용 How to Build a Centralized PDF Generation Service with ASP.NET Core and IronPDF 커티스 차우 업데이트됨:12월 20, 2025 다운로드 IronPDF NuGet 다운로드 DLL 다운로드 윈도우 설치 프로그램 무료 체험 시작하기 LLM용 사본 LLM용 사본 LLM용 마크다운 형식으로 페이지를 복사하세요 ChatGPT에서 열기 ChatGPT에 이 페이지에 대해 문의하세요 제미니에서 열기 제미니에게 이 페이지에 대해 문의하세요 Grok에서 열기 Grok에게 이 페이지에 대해 문의하세요 혼란 속에서 열기 Perplexity에게 이 페이지에 대해 문의하세요 공유하다 페이스북에 공유하기 트위터에 공유하기 LinkedIn에 공유하기 URL 복사 이메일로 기사 보내기 Build a production-ready .NET PDF API using ASP.NET Core and IronPDF to centralize PDF generation logic, enabling consistent document creation across your applications with RESTful endpoints for HTML-to-PDF conversion, merging, watermarking, and dynamic template processing. When working with modern applications, .NET developers often need to build a centralized PDF generation service. Whether you're generating invoices, reports, certificates, or contracts, having a dedicated .NET PDF API improves your PDF generation workflow. How does it help? It provides consistency, maintainability, and scalability across your desktop and web applications. Managing document content, PDF pages, and PDF form fields becomes straightforward. In this tutorial, you'll learn how to build a production-ready PDF API using ASP.NET Core and IronPDF, a powerful .NET PDF library. We'll create RESTful endpoints that generate PDFs from HTML, merge documents, add watermarks, and handle various real-world PDF scenarios in your Web API. Why Build a Dedicated PDF API? Before diving into the code, let's understand why creating a dedicated PDF API makes sense: Centralized Logic: All PDF generation logic lives in one place, simplifying maintenance and updates. Microservice Architecture: Perfect for service-oriented architectures where different apps need PDF capabilities. Performance Optimization: Easier to scale and optimize a dedicated service for large PDFs, multiple pages, and dynamic data using async operations and performance techniques. Language Agnostic: Any client application can consume the API regardless of programming language. Consistent Output: Ensures all PDFs across your organization maintain consistent layout, formatting, and content. Ready to start building? Download IronPDF's free trial and follow along with this tutorial to programmatically create PDF files in your .NET Framework projects. What Makes IronPDF the Complete .NET PDF Library? IronPDF stands out as the premier PDF library for .NET developers, offering a comprehensive set of features that make PDF generation in Web API projects straightforward and reliable. Built on a Chrome rendering engine, it ensures pixel-perfect HTML-to-PDF conversions in just a few lines of code while maintaining all styling, JavaScript execution, and responsive layouts. Key capabilities that make IronPDF ideal for .NET PDF API development: Chrome-Based Rendering: Uses Google Chrome's engine for accurate HTML-to-PDF conversion with full support for embedded images and web assets. Rich Feature Set: Edit documents with digital signatures, PDF forms, annotations, encryption, compression, and more. Create Secure PDFs: Manage sensitive content with encryption, digital signatures, and document protection. Multiple Input Formats: Use HTML, URLs, images, and Office documents to create PDFs. Advanced Manipulation: Merge pages, split documents, apply watermarks, create interactive forms, and manipulate PDFs programmatically. Cross-Platform Support: Works on Windows, Linux, macOS, Docker, and cloud platforms. Performance Optimized: Async operations, efficient memory management, and fast rendering with render delay options. How to Set Up Your PDF Document API Project? Let's start by creating a new ASP.NET Core Web API project and installing the necessary packages. What Are the Prerequisites? .NET 6.0 SDK or later Visual Studio 2022 or Visual Studio Code Postman or similar API testing tool for testing your PDF REST API How Do I Create the Project? First, let's create the project where we'll build our PDF generation tool. dotnet new webapi -n PdfApiService cd PdfApiService dotnet new webapi -n PdfApiService cd PdfApiService SHELL How Do I Install IronPDF? Next, add IronPDF to your project via NuGet: dotnet add package IronPDF dotnet add package IronPDF SHELL Or, using the NuGet Package Manager Console in Visual Studio: Install-Package IronPDF For advanced installation options, including platform-specific packages, Docker setup, or Linux configurations, check the IronPDF installation documentation. What Project Structure Should I Use? Good C# development requires maintaining a clean and well-structured project folder. For example: How to Create Your First PDF Endpoint? Let's build a simple endpoint that converts HTML to PDF format. First, create the service interface and implementation: How Do I Create the PDF Service? First, add the following to your IPdfService.cs file: public interface IPdfService { byte[] GeneratePdfFromHtml(string htmlContent); byte[] GeneratePdfFromUrl(string url); } public interface IPdfService { byte[] GeneratePdfFromHtml(string htmlContent); byte[] GeneratePdfFromUrl(string url); } $vbLabelText $csharpLabel In the PdfService.cs file, add this: using IronPdf; public class PdfService : IPdfService { private readonly ChromePdfRenderer _renderer; public PdfService() { _renderer = new ChromePdfRenderer(); // Configure rendering options for optimal PDF generation in .NET _renderer.RenderingOptions.MarginTop = 20; _renderer.RenderingOptions.MarginBottom = 20; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; } public byte[] GeneratePdfFromHtml(string htmlContent) { // Generate PDF from HTML using the .NET PDF API var pdf = _renderer.RenderHtmlAsPdf(htmlContent); return pdf.BinaryData; } public byte[] GeneratePdfFromUrl(string url) { // Convert URL to PDF in the REST API var pdf = _renderer.RenderUrlAsPdf(url); return pdf.BinaryData; } } using IronPdf; public class PdfService : IPdfService { private readonly ChromePdfRenderer _renderer; public PdfService() { _renderer = new ChromePdfRenderer(); // Configure rendering options for optimal PDF generation in .NET _renderer.RenderingOptions.MarginTop = 20; _renderer.RenderingOptions.MarginBottom = 20; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; } public byte[] GeneratePdfFromHtml(string htmlContent) { // Generate PDF from HTML using the .NET PDF API var pdf = _renderer.RenderHtmlAsPdf(htmlContent); return pdf.BinaryData; } public byte[] GeneratePdfFromUrl(string url) { // Convert URL to PDF in the REST API var pdf = _renderer.RenderUrlAsPdf(url); return pdf.BinaryData; } } $vbLabelText $csharpLabel The PdfService handles converting HTML into PDF. Using IronPDF's ChromePdfRenderer, this class configures defaults like page margins and background rendering for professional results. For advanced rendering configurations, explore IronPDF's rendering options. When the controller passes raw HTML, the service renders it into a high-quality PDF and returns the byte data for download. It also converts entire web pages directly into PDFs using URL to PDF conversion. How Do I Create the Controller? Now create the controller for your API. This provides an endpoint that generates PDF files from HTML and lets you download and save PDF documents to your system. // Controllers/PdfController.cs using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class PdfController : ControllerBase { private readonly IPdfService _pdfService; public PdfController(IPdfService pdfService) { _pdfService = pdfService; } [HttpPost("html-to-pdf")] public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request) { try { var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent); // Return as downloadable file return File(pdfBytes, "application/pdf", "document.pdf"); } catch (Exception ex) { return BadRequest($"Error generating PDF: {ex.Message}"); } } } // Controllers/PdfController.cs using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class PdfController : ControllerBase { private readonly IPdfService _pdfService; public PdfController(IPdfService pdfService) { _pdfService = pdfService; } [HttpPost("html-to-pdf")] public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request) { try { var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent); // Return as downloadable file return File(pdfBytes, "application/pdf", "document.pdf"); } catch (Exception ex) { return BadRequest($"Error generating PDF: {ex.Message}"); } } } $vbLabelText $csharpLabel Then, in the HtmlRequest.cs file, add this: // Models/HtmlRequest.cs public class HtmlRequest { public string HtmlContent { get; set; } public string FileName { get; set; } = "document.pdf"; } // Models/HtmlRequest.cs public class HtmlRequest { public string HtmlContent { get; set; } public string FileName { get; set; } = "document.pdf"; } $vbLabelText $csharpLabel This sets up an API endpoint that converts HTML into a downloadable PDF. When someone sends HTML to api/pdf/html-to-pdf, the PdfController delegates conversion to the service. Once created, the controller returns the PDF as a downloadable file. The request uses the HtmlRequest model, containing the HTML and an optional filename. This makes it easy for clients to send HTML and receive a polished PDF. How Do I Register Services? Update your Program.cs to register the PDF service: var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Register PDF service builder.Services.AddSingleton<IPdfService, PdfService>(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapControllers(); app.Run(); var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Register PDF service builder.Services.AddSingleton<IPdfService, PdfService>(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapControllers(); app.Run(); $vbLabelText $csharpLabel How to Handle Different Response Types? Your API should support different ways of returning PDFs based on client needs: [HttpPost("generate")] public IActionResult GeneratePdf([FromBody] PdfRequest request) { var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent); switch (request.ResponseType?.ToLower()) { case "base64": return Ok(new { data = Convert.ToBase64String(pdfBytes), filename = request.FileName }); case "inline": return File(pdfBytes, "application/pdf"); default: // download return File(pdfBytes, "application/pdf", request.FileName); } } [HttpPost("generate")] public IActionResult GeneratePdf([FromBody] PdfRequest request) { var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent); switch (request.ResponseType?.ToLower()) { case "base64": return Ok(new { data = Convert.ToBase64String(pdfBytes), filename = request.FileName }); case "inline": return File(pdfBytes, "application/pdf"); default: // download return File(pdfBytes, "application/pdf", request.FileName); } } $vbLabelText $csharpLabel This adds a flexible PDF generation endpoint. Instead of forcing downloads, the GeneratePdf method lets clients choose how they receive results: as a download, inline in browser, or Base64 encoded for API use. The PdfRequest model extends HtmlRequest with a ResponseType option. This gives users control over PDF delivery, making the API more versatile. For handling PDFs in memory without file system access, see IronPDF's memory stream documentation. When we run our program, we'll see this output on Swagger: How to Implement Common PDF Operations? Let's expand our service to handle various PDF generation scenarios: How Do I Convert URLs to PDF? [HttpPost("url-to-pdf")] public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request) { try { var pdfBytes = await Task.Run(() => _pdfService.GeneratePdfFromUrl(request.Url)); return File(pdfBytes, "application/pdf", $"{request.FileName ?? "website"}.pdf"); } catch (Exception ex) { return BadRequest($"Failed to convert URL: {ex.Message}"); } } public class UrlRequest { public string Url { get; set; } public string FileName { get; set; } } [HttpPost("url-to-pdf")] public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request) { try { var pdfBytes = await Task.Run(() => _pdfService.GeneratePdfFromUrl(request.Url)); return File(pdfBytes, "application/pdf", $"{request.FileName ?? "website"}.pdf"); } catch (Exception ex) { return BadRequest($"Failed to convert URL: {ex.Message}"); } } public class UrlRequest { public string Url { get; set; } public string FileName { get; set; } } $vbLabelText $csharpLabel This endpoint converts URLs into downloadable PDFs. When a POST request hits /api/pdf/url-to-pdf, the controller uses _pdfService to convert the URL into PDF bytes in the background, then returns them for download. If conversion fails, it responds with a clear error message. For websites with authentication, check out IronPDF's login documentation. Let's try using the URL "https://www.apple.com/nz" and test the POST request. Below is the output we obtained: What Does the Output Look Like? How Do I Add Custom Watermarks? public byte[] AddWatermarkFromFile(string filePath, string watermarkText) { // Load PDF directly from file var pdf = PdfDocument.FromFile(filePath); pdf.ApplyWatermark( $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>", 75, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center ); return pdf.BinaryData; } public byte[] AddWatermarkFromFile(string filePath, string watermarkText) { // Load PDF directly from file var pdf = PdfDocument.FromFile(filePath); pdf.ApplyWatermark( $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>", 75, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center ); return pdf.BinaryData; } $vbLabelText $csharpLabel This manually loads a local file for testing. You can adjust this so your PDF API generates a PDF, then applies custom watermarks easily. For advanced watermarking options, including image watermarks and custom positioning, see the watermarking guide. What Does the Watermark Output Look Like? How to Add Dynamic Data with Templates? For real-world applications, you'll often need to generate PDFs from templates with dynamic data: [HttpPost("from-template")] public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request) { // Simple template replacement var html = request.Template; foreach (var item in request.Data) { html = html.Replace($"{{{{{item.Key}}}}}", item.Value); } var pdfBytes = _pdfService.GeneratePdfFromHtml(html); return File(pdfBytes, "application/pdf", request.FileName); } public class TemplateRequest { public string Template { get; set; } public Dictionary<string, string> Data { get; set; } public string FileName { get; set; } = "document.pdf"; } [HttpPost("from-template")] public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request) { // Simple template replacement var html = request.Template; foreach (var item in request.Data) { html = html.Replace($"{{{{{item.Key}}}}}", item.Value); } var pdfBytes = _pdfService.GeneratePdfFromHtml(html); return File(pdfBytes, "application/pdf", request.FileName); } public class TemplateRequest { public string Template { get; set; } public Dictionary<string, string> Data { get; set; } public string FileName { get; set; } = "document.pdf"; } $vbLabelText $csharpLabel For advanced template scenarios with Razor, Handlebars, or other engines, check out IronPDF's HTML to PDF documentation. You can also explore CSHTML to PDF conversion for MVC applications and Razor to PDF for Blazor applications. For headless Razor rendering, see the CSHTML headless guide. How to Optimize Performance? When building a production PDF API, performance is crucial. Here are key optimization strategies: Why Use Async Operations? Use asynchronous coding when your projects involve I/O operations. This helps especially when your PDF content comes from external resources like: Downloading HTML pages (RenderUrlAsPdf) Fetching images, CSS, or fonts over HTTP Reading/writing files to disk or cloud storage These operations can block threads, but async prevents API threads from waiting idle. For comprehensive async PDF generation patterns, see the async PDF generation guide. Example: public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent) { return await Task.Run(() => { var pdf = _renderer.RenderHtmlAsPdf(htmlContent); return pdf.BinaryData; }); } public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent) { return await Task.Run(() => { var pdf = _renderer.RenderHtmlAsPdf(htmlContent); return pdf.BinaryData; }); } $vbLabelText $csharpLabel For parallel PDF generation scenarios, explore multi-threading and parallel processing techniques. What Rendering Options Should I Configure? Configure IronPDF for optimal performance: _renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed _renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print; _renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS _renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout _renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed _renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print; _renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS _renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout $vbLabelText $csharpLabel For comprehensive rendering configuration options, including viewport settings, custom paper sizes, and page orientation, see the rendering options documentation. How to Secure Your PDF API? Security is essential for any production API. Here's a simple API key authentication approach: // Middleware/ApiKeyMiddleware.cs public class ApiKeyMiddleware { private readonly RequestDelegate _next; private const string ApiKeyHeader = "X-API-Key"; public ApiKeyMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey)) { context.Response.StatusCode = 401; await context.Response.WriteAsync("API Key required"); return; } // Validate API key (in production, check against database) var validApiKey = context.RequestServices .GetRequiredService<IConfiguration>()["ApiKey"]; if (apiKey != validApiKey) { context.Response.StatusCode = 403; await context.Response.WriteAsync("Invalid API Key"); return; } await _next(context); } } // In Program.cs app.UseMiddleware<ApiKeyMiddleware>(); // Middleware/ApiKeyMiddleware.cs public class ApiKeyMiddleware { private readonly RequestDelegate _next; private const string ApiKeyHeader = "X-API-Key"; public ApiKeyMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey)) { context.Response.StatusCode = 401; await context.Response.WriteAsync("API Key required"); return; } // Validate API key (in production, check against database) var validApiKey = context.RequestServices .GetRequiredService<IConfiguration>()["ApiKey"]; if (apiKey != validApiKey) { context.Response.StatusCode = 403; await context.Response.WriteAsync("Invalid API Key"); return; } await _next(context); } } // In Program.cs app.UseMiddleware<ApiKeyMiddleware>(); $vbLabelText $csharpLabel For advanced authentication scenarios, consider: JWT Authentication - Industry standard for API authentication OAuth 2.0 - For third-party integrations Azure AD Integration - Enterprise authentication API Rate Limiting - Prevent abuse and ensure fair usage HTTP Headers - Custom header configuration for enhanced security For PDF-specific security, implement password protection, digital signatures, and PDF sanitization to remove potentially malicious content. How to Build a Real-World Invoice Generation API? Let's build a practical invoice generation endpoint demonstrating a complete implementation. This example shows how a production .NET PDF API generates professional invoices with dynamic data. 지금 바로 IronPDF으로 시작하세요. 무료로 시작하세요 First, create a new file in your Models folder. Here, I've called mine Invoice.cs. Then add the following code: public class Invoice { public string InvoiceNumber { get; set; } public DateTime Date { get; set; } public string CustomerName { get; set; } public string CustomerAddress { get; set; } public List<InvoiceItem> Items { get; set; } public decimal Tax { get; set; } } public class InvoiceItem { public string Description { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal Total => Quantity * UnitPrice; } public class Invoice { public string InvoiceNumber { get; set; } public DateTime Date { get; set; } public string CustomerName { get; set; } public string CustomerAddress { get; set; } public List<InvoiceItem> Items { get; set; } public decimal Tax { get; set; } } public class InvoiceItem { public string Description { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal Total => Quantity * UnitPrice; } $vbLabelText $csharpLabel Next, create a new service file for the invoice generator. In your Services folder, add the following code. I created a file called InvoiceService.cs. This code handles the styling and layout of your Invoice PDF: public class InvoiceService { private readonly ChromePdfRenderer _renderer; public InvoiceService() { _renderer = new ChromePdfRenderer(); _renderer.RenderingOptions.MarginTop = 10; _renderer.RenderingOptions.MarginBottom = 10; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; } public byte[] GenerateInvoice(Invoice invoice) { var html = BuildInvoiceHtml(invoice); // Add footer with page numbers _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter { MaxHeight = 15, HtmlFragment = "<center><i>{page} of {total-pages}</i></center>", DrawDividerLine = true }; var pdf = _renderer.RenderHtmlAsPdf(html); return pdf.BinaryData; } private string BuildInvoiceHtml(Invoice invoice) { var subtotal = invoice.Items.Sum(i => i.Total); var taxAmount = subtotal * (invoice.Tax / 100); var total = subtotal + taxAmount; var itemsHtml = string.Join("", invoice.Items.Select(item => $@"<tr> <td>{item.Description}</td> <td class='text-center'>{item.Quantity}</td> <td class='text-right'>${item.UnitPrice:F2}</td> <td class='text-right'>${item.Total:F2}</td> </tr>")); return $@" <!DOCTYPE html> <html> <head> <style> body {{ font-family: Arial, sans-serif; }} .invoice-header {{ background-color: #f8f9fa; padding: 20px; margin-bottom: 20px; }} table {{ width: 100%; border-collapse: collapse; }} th, td {{ padding: 10px; border-bottom: 1px solid #ddd; }} th {{ background-color: #007bff; color: white; }} .text-right {{ text-align: right; }} .text-center {{ text-align: center; }} .total-section {{ margin-top: 20px; text-align: right; }} </style> </head> <body> <div class='invoice-header'> <h1>Invoice #{invoice.InvoiceNumber}</h1> <p>Date: {invoice.Date:yyyy-MM-dd}</p> </div> <div> <h3>Bill To:</h3> <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p> </div> <table> <thead> <tr> <th>Description</th> <th>Quantity</th> <th>Unit Price</th> <th>Total</th> </tr> </thead> <tbody> {itemsHtml} </tbody> </table> <div class='total-section'> <p>Subtotal: ${subtotal:F2}</p> <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p> <h3>Total: ${total:F2}</h3> </div> </body> </html>"; } } public class InvoiceService { private readonly ChromePdfRenderer _renderer; public InvoiceService() { _renderer = new ChromePdfRenderer(); _renderer.RenderingOptions.MarginTop = 10; _renderer.RenderingOptions.MarginBottom = 10; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; } public byte[] GenerateInvoice(Invoice invoice) { var html = BuildInvoiceHtml(invoice); // Add footer with page numbers _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter { MaxHeight = 15, HtmlFragment = "<center><i>{page} of {total-pages}</i></center>", DrawDividerLine = true }; var pdf = _renderer.RenderHtmlAsPdf(html); return pdf.BinaryData; } private string BuildInvoiceHtml(Invoice invoice) { var subtotal = invoice.Items.Sum(i => i.Total); var taxAmount = subtotal * (invoice.Tax / 100); var total = subtotal + taxAmount; var itemsHtml = string.Join("", invoice.Items.Select(item => $@"<tr> <td>{item.Description}</td> <td class='text-center'>{item.Quantity}</td> <td class='text-right'>${item.UnitPrice:F2}</td> <td class='text-right'>${item.Total:F2}</td> </tr>")); return $@" <!DOCTYPE html> <html> <head> <style> body {{ font-family: Arial, sans-serif; }} .invoice-header {{ background-color: #f8f9fa; padding: 20px; margin-bottom: 20px; }} table {{ width: 100%; border-collapse: collapse; }} th, td {{ padding: 10px; border-bottom: 1px solid #ddd; }} th {{ background-color: #007bff; color: white; }} .text-right {{ text-align: right; }} .text-center {{ text-align: center; }} .total-section {{ margin-top: 20px; text-align: right; }} </style> </head> <body> <div class='invoice-header'> <h1>Invoice #{invoice.InvoiceNumber}</h1> <p>Date: {invoice.Date:yyyy-MM-dd}</p> </div> <div> <h3>Bill To:</h3> <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p> </div> <table> <thead> <tr> <th>Description</th> <th>Quantity</th> <th>Unit Price</th> <th>Total</th> </tr> </thead> <tbody> {itemsHtml} </tbody> </table> <div class='total-section'> <p>Subtotal: ${subtotal:F2}</p> <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p> <h3>Total: ${total:F2}</h3> </div> </body> </html>"; } } $vbLabelText $csharpLabel Finally, create a new Controller to access and create invoices using the API: [ApiController] [Route("api/[controller]")] public class InvoiceController : ControllerBase { private readonly InvoiceService _invoiceService; public InvoiceController(InvoiceService invoiceService) { _invoiceService = invoiceService; } [HttpPost("generate")] public IActionResult GenerateInvoice([FromBody] Invoice invoice) { try { var pdfBytes = _invoiceService.GenerateInvoice(invoice); var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { return StatusCode(500, $"Error generating invoice: {ex.Message}"); } } } [ApiController] [Route("api/[controller]")] public class InvoiceController : ControllerBase { private readonly InvoiceService _invoiceService; public InvoiceController(InvoiceService invoiceService) { _invoiceService = invoiceService; } [HttpPost("generate")] public IActionResult GenerateInvoice([FromBody] Invoice invoice) { try { var pdfBytes = _invoiceService.GenerateInvoice(invoice); var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { return StatusCode(500, $"Error generating invoice: {ex.Message}"); } } } $vbLabelText $csharpLabel For advanced invoice features, consider adding barcodes, QR codes, page numbers, and custom headers/footers. You can also implement PDF/A compliance for long-term archival or integrate with electronic signature workflows. What Does the Invoice Output Look Like? What Are the Container Deployment Considerations? While this tutorial focuses on local development, here's a brief overview of containerizing your PDF API: How Do I Create a Basic Dockerfile? FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["PdfApiService.csproj", "."] RUN dotnet restore COPY . . RUN dotnet build -c Release -o /app/build FROM build AS publish RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . # IronPDF requires additional dependencies on Linux RUN apt-get update && apt-get install -y \ libgdiplus \ libc6-dev \ libx11-dev \ && rm -rf /var/lib/apt/lists/* ENTRYPOINT ["dotnet", "PdfApiService.dll"] For detailed deployment guides for your .NET PDF API, see: IronPDF Docker Documentation - Complete containerization guide IronPDF Azure Deployment - Azure Functions and App Service IronPDF AWS Deployment - Lambda and EC2 deployment IronPDF Linux Setup - Linux-specific configuration Running as Remote Container - IronPDF Engine containerization Native vs Remote Engine - Deployment architecture options What Are the Error Handling Best Practices? For fault-tolerant programs, implement a global error handler for consistent error responses: // Middleware/ErrorHandlingMiddleware.cs public class ErrorHandlingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<ErrorHandlingMiddleware> _logger; public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path); await HandleExceptionAsync(context, ex); } } private static async Task HandleExceptionAsync(HttpContext context, Exception ex) { context.Response.ContentType = "application/json"; context.Response.StatusCode = ex switch { ArgumentNullException => 400, UnauthorizedAccessException => 401, _ => 500 }; var response = new { error = "An error occurred processing your request", message = ex.Message, statusCode = context.Response.StatusCode }; await context.Response.WriteAsync(JsonSerializer.Serialize(response)); } } // Middleware/ErrorHandlingMiddleware.cs public class ErrorHandlingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<ErrorHandlingMiddleware> _logger; public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path); await HandleExceptionAsync(context, ex); } } private static async Task HandleExceptionAsync(HttpContext context, Exception ex) { context.Response.ContentType = "application/json"; context.Response.StatusCode = ex switch { ArgumentNullException => 400, UnauthorizedAccessException => 401, _ => 500 }; var response = new { error = "An error occurred processing your request", message = ex.Message, statusCode = context.Response.StatusCode }; await context.Response.WriteAsync(JsonSerializer.Serialize(response)); } } $vbLabelText $csharpLabel For specific IronPDF troubleshooting scenarios, refer to: Quick troubleshooting guide Engineering support guide Custom logging configuration Memory leak prevention Performance optimization tips Ready to Build Your Production .NET PDF API? You've now built a robust .NET PDF API using ASP.NET Core and IronPDF that handles various document generation scenarios. This REST API provides a solid foundation for centralized PDF operations in your applications. Key takeaways: IronPDF makes PDF generation in Web API projects straightforward with Chrome-based rendering. Easily edit existing PDFs with IronPDF's advanced editing tools. RESTful design principles ensure your PDF API is intuitive and maintainable. Proper error handling and security measures are essential for production. Performance optimization through async operations and caching improves scalability. Full support for desktop and web applications with scalable document solutions. IronPDF lets developers create PDFs, save PDF files, and convert HTML efficiently, making it the essential PDF API for modern .NET Framework applications. What Are the Next Steps? Ready to implement IronPDF in your production .NET PDF API? Here are your next actions: Start your free trial - Test IronPDF with full functionality in your development environment. Explore advanced features - Check out digital signatures, PDF forms, PDF/A compliance, metadata management, and other advanced PDF features. Scale with confidence - Review licensing options for your production API needs, including extensions and upgrades. Build your .NET PDF API today and streamline document generation across your entire application ecosystem with IronPDF! 자주 묻는 질문 .NET 애플리케이션에서 IronPDF는 어떤 용도로 사용되나요? IronPDF는 .NET 애플리케이션 내에서 PDF를 생성, 조작 및 변환하는 데 사용되므로 중앙 집중식 PDF 서비스를 만드는 데 이상적입니다. IronPDF를 ASP.NET Core와 어떻게 통합할 수 있나요? IronPDF NuGet 패키지를 설치하여 IronPDF를 ASP.NET Core와 통합할 수 있으므로 중앙 집중식 PDF 생성 서비스를 구축할 수 있습니다. PDF 생성을 위한 IronPDF의 주요 기능은 무엇인가요? IronPDF의 주요 기능으로는 HTML을 PDF로 변환, PDF 병합 및 분할, 머리글 및 바닥글 추가, 텍스트 및 이미지 추출 등이 있습니다. IronPDF는 복잡한 PDF 레이아웃을 처리할 수 있나요? 예, IronPDF는 HTML 및 CSS 콘텐츠를 정확하게 렌더링된 PDF 문서로 변환할 수 있기 때문에 복잡한 PDF 레이아웃을 처리할 수 있습니다. IronPDF로 PDF 생성을 사용자 지정할 수 있나요? 예, IronPDF를 사용하면 페이지 크기, 여백 설정, 워터마크 또는 주석 추가 등 PDF 생성 시 사용자 정의가 가능합니다. IronPDF는 PDF 보안 기능을 지원하나요? IronPDF는 생성된 PDF 문서를 보호하기 위해 비밀번호 보호 및 암호화와 같은 PDF 보안 기능을 지원합니다. IronPDF는 어떤 형식을 PDF로 변환할 수 있나요? IronPDF는 HTML, URL, ASPX 파일 등 다양한 형식을 PDF로 변환할 수 있어 다양한 사용 사례에 다용도로 활용할 수 있습니다. IronPDF는 대규모 PDF 생성을 어떻게 처리하나요? IronPDF는 성능에 최적화되어 있어 .NET 애플리케이션 내에서 대규모 PDF 생성 작업을 효율적으로 처리할 수 있습니다. IronPDF를 클라우드 기반 애플리케이션에서 사용할 수 있나요? 예, IronPDF는 클라우드 기반 애플리케이션에서 사용할 수 있으며 확장 가능한 PDF 서비스를 위해 Azure 및 AWS와 같은 플랫폼에 배포를 지원합니다. IronPDF는 어떤 버전의 .NET을 지원하나요? IronPDF는 .NET Core 및 .NET Framework를 포함한 여러 .NET 버전을 지원하므로 다양한 프로젝트와의 호환성을 보장합니다. 커티스 차우 지금 바로 엔지니어링 팀과 채팅하세요 기술 문서 작성자 커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다. 커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다. 관련 기사 업데이트됨 1월 22, 2026 How to Create PDF Documents in .NET with IronPDF: Complete Guide Discover effective methods to create PDF files in C# for developers. Enhance your coding skills and streamline your projects. Read the article now! 더 읽어보기 업데이트됨 1월 21, 2026 How to Merge PDF Files in VB.NET: Complete Tutorial Merge PDF VB NET with IronPDF. Learn to combine multiple PDF files into one document using simple VB.NET code. Step-by-step examples included. 더 읽어보기 업데이트됨 1월 21, 2026 C# PDFWriter Tutorial: Create PDF Documents in .NET Learn to create PDFs efficiently using C# PDFWriter with this step-by-step guide for developers. Read the article to enhance your skills today! 더 읽어보기 Using IronPDF and OCRNet to Create and Scan PDF Files in C#Creating a .NET Core PDF Generator ...
업데이트됨 1월 22, 2026 How to Create PDF Documents in .NET with IronPDF: Complete Guide Discover effective methods to create PDF files in C# for developers. Enhance your coding skills and streamline your projects. Read the article now! 더 읽어보기
업데이트됨 1월 21, 2026 How to Merge PDF Files in VB.NET: Complete Tutorial Merge PDF VB NET with IronPDF. Learn to combine multiple PDF files into one document using simple VB.NET code. Step-by-step examples included. 더 읽어보기
업데이트됨 1월 21, 2026 C# PDFWriter Tutorial: Create PDF Documents in .NET Learn to create PDFs efficiently using C# PDFWriter with this step-by-step guide for developers. Read the article to enhance your skills today! 더 읽어보기