MIGRATION GUIDES How to Migrate from Gotenberg to IronPDF in C# 커티스 차우 게시됨:1월 25, 2026 다운로드 IronPDF NuGet 다운로드 DLL 다운로드 윈도우 설치 프로그램 무료 체험 시작하기 LLM용 사본 LLM용 사본 LLM용 마크다운 형식으로 페이지를 복사하세요 ChatGPT에서 열기 ChatGPT에 이 페이지에 대해 문의하세요 제미니에서 열기 제미니에게 이 페이지에 대해 문의하세요 Grok에서 열기 Grok에게 이 페이지에 대해 문의하세요 혼란 속에서 열기 Perplexity에게 이 페이지에 대해 문의하세요 공유하다 페이스북에 공유하기 트위터에 공유하기 LinkedIn에 공유하기 URL 복사 이메일로 기사 보내기 Migrating from Gotenberg to IronPDF transforms your .NET PDF workflow from a Docker-based microservice architecture with HTTP API calls to an in-process native C# library. This guide provides a comprehensive, step-by-step migration path that eliminates infrastructure overhead, network latency, and container management complexity for professional .NET developers. Why Migrate from Gotenberg to IronPDF The Gotenberg Architecture Problem Gotenberg is a Docker-based microservice architecture for PDF generation. While powerful and flexible, it introduces significant complexity for C# applications: Infrastructure Overhead: Requires Docker, container orchestration (Kubernetes/Docker Compose), service discovery, and load balancing. Every deployment becomes more complex. Network Latency: Every PDF operation requires an HTTP call to a separate service—adding 10-100ms+ per request. This latency compounds quickly in high-volume scenarios. Cold Start Issues: Container startup can add 2-5 seconds to first requests. Every pod restart, every scale-up event, and every deployment triggers cold starts. Operational Complexity: You must manage container health, scaling, logging, and monitoring as separate concerns from your main application. Multipart Form Data: Every request requires constructing multipart/form-data payloads—verbose, error-prone, and tedious to maintain. Failure Points: Network timeouts, service unavailability, and container crashes all become your responsibility to handle. Version Management: Gotenberg images update separately from your application; API changes can break integrations unexpectedly. Gotenberg vs IronPDF Comparison Aspect Gotenberg IronPDF Deployment Docker container + orchestration Single NuGet package Architecture Microservice (REST API) In-process library Latency per request 10-100ms+ (network round-trip) < 1ms overhead Cold start 2-5 seconds (container init) 1-2 seconds (first render only) Infrastructure Docker, Kubernetes, load balancers None required Failure Modes Network, container, service failures Standard .NET exceptions API Style REST multipart/form-data Native C# method calls Scaling Horizontal (more containers) Vertical (in-process) Debugging Distributed tracing needed Standard debugger Version Control Container image tags NuGet package versions For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a future-proof foundation with zero infrastructure dependencies that integrates natively with modern .NET patterns. Migration Complexity Assessment Estimated Effort by Feature Feature Migration Complexity HTML to PDF Very Low URL to PDF Very Low Custom Paper Size Low Margins Low PDF Merging Low Headers/Footers Medium Wait Delays Low PDF/A Conversion Low Paradigm Shift The fundamental shift in this Gotenberg migration is from HTTP API calls with multipart form data to native C# method calls: Gotenberg: HTTP POST multipart/form-data to Docker container IronPDF: Direct method calls on C# objects Before You Start Prerequisites .NET Version: IronPDF supports .NET Framework 4.6.2+ and .NET Core 3.1+ / .NET 5/6/7/8/9+ License Key: Obtain your IronPDF license key from ironpdf.com Plan Infrastructure Removal: Document Gotenberg containers for decommissioning post-migration Identify All Gotenberg Usage # Find direct HTTP calls to Gotenberg grep -r "gotenberg\|/forms/chromium\|/forms/libreoffice\|/forms/pdfengines" --include="*.cs" . # Find GotenbergSharpApiClient usage grep -r "GotenbergSharpClient\|Gotenberg.Sharp\|ChromiumRequest" --include="*.cs" . # Find Docker/Kubernetes Gotenberg configuration grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" . # Find direct HTTP calls to Gotenberg grep -r "gotenberg\|/forms/chromium\|/forms/libreoffice\|/forms/pdfengines" --include="*.cs" . # Find GotenbergSharpApiClient usage grep -r "GotenbergSharpClient\|Gotenberg.Sharp\|ChromiumRequest" --include="*.cs" . # Find Docker/Kubernetes Gotenberg configuration grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" . SHELL NuGet Package Changes # Remove Gotenberg client (if using) dotnet remove package Gotenberg.Sharp.API.Client # Install IronPDF dotnet add package IronPdf # Remove Gotenberg client (if using) dotnet remove package Gotenberg.Sharp.API.Client # Install IronPDF dotnet add package IronPdf SHELL Quick Start Migration Step 1: Update License Configuration Before (Gotenberg): Gotenberg requires no license but requires Docker infrastructure with container URLs. private readonly string _gotenbergUrl = "http://localhost:3000"; private readonly string _gotenbergUrl = "http://localhost:3000"; $vbLabelText $csharpLabel After (IronPDF): // Set once at application startup IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"; // Set once at application startup IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"; $vbLabelText $csharpLabel Step 2: Update Namespace Imports // Before (Gotenberg) using System.Net.Http; using System.Threading.Tasks; using System.IO; // After (IronPDF) using IronPdf; using IronPdf.Rendering; // Before (Gotenberg) using System.Net.Http; using System.Threading.Tasks; using System.IO; // After (IronPDF) using IronPdf; using IronPdf.Rendering; $vbLabelText $csharpLabel Complete API Reference Gotenberg Endpoint to IronPDF Mapping Gotenberg Route IronPDF Equivalent POST /forms/chromium/convert/html ChromePdfRenderer.RenderHtmlAsPdf() POST /forms/chromium/convert/url ChromePdfRenderer.RenderUrlAsPdf() POST /forms/pdfengines/merge PdfDocument.Merge() POST /forms/pdfengines/convert pdf.SaveAs() with settings GET /health N/A Form Parameter to RenderingOptions Mapping Gotenberg Parameter IronPDF Property Conversion Notes paperWidth (inches) RenderingOptions.PaperSize Use enum or custom size paperHeight (inches) RenderingOptions.PaperSize Use enum or custom size marginTop (inches) RenderingOptions.MarginTop Multiply by 25.4 for mm marginBottom (inches) RenderingOptions.MarginBottom Multiply by 25.4 for mm printBackground RenderingOptions.PrintHtmlBackgrounds Boolean landscape RenderingOptions.PaperOrientation Landscape enum waitDelay RenderingOptions.RenderDelay Convert to milliseconds Code Migration Examples Example 1: Basic HTML to PDF Before (Gotenberg): using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergExample { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"; content.Add(new StringContent(html), "files", "index.html"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("output.pdf", pdfBytes); Console.WriteLine("PDF generated successfully"); } } using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergExample { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"; content.Add(new StringContent(html), "files", "index.html"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("output.pdf", pdfBytes); Console.WriteLine("PDF generated successfully"); } } $vbLabelText $csharpLabel After (IronPDF): // NuGet: Install-Package IronPdf using System; using IronPdf; class IronPdfExample { static void Main() { var renderer = new ChromePdfRenderer(); var html = "<html><body><h1>Hello from IronPDF</h1></body></html>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("output.pdf"); Console.WriteLine("PDF generated successfully"); } } // NuGet: Install-Package IronPdf using System; using IronPdf; class IronPdfExample { static void Main() { var renderer = new ChromePdfRenderer(); var html = "<html><body><h1>Hello from IronPDF</h1></body></html>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("output.pdf"); Console.WriteLine("PDF generated successfully"); } } $vbLabelText $csharpLabel The difference is substantial: Gotenberg requires constructing an HttpClient, building MultipartFormDataContent, making an async HTTP POST to a running Docker container, and handling the byte array response. IronPDF reduces this to three lines with a ChromePdfRenderer method call—no network overhead, no container dependency, no async complexity. See the HTML to PDF documentation for additional rendering options. Example 2: URL to PDF Conversion Before (Gotenberg): using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergUrlToPdf { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); content.Add(new StringContent("https://example.com"), "url"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("webpage.pdf", pdfBytes); Console.WriteLine("PDF from URL generated successfully"); } } using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergUrlToPdf { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); content.Add(new StringContent("https://example.com"), "url"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("webpage.pdf", pdfBytes); Console.WriteLine("PDF from URL generated successfully"); } } $vbLabelText $csharpLabel After (IronPDF): // NuGet: Install-Package IronPdf using System; using IronPdf; class IronPdfUrlToPdf { static void Main() { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://example.com"); pdf.SaveAs("webpage.pdf"); Console.WriteLine("PDF from URL generated successfully"); } } // NuGet: Install-Package IronPdf using System; using IronPdf; class IronPdfUrlToPdf { static void Main() { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://example.com"); pdf.SaveAs("webpage.pdf"); Console.WriteLine("PDF from URL generated successfully"); } } $vbLabelText $csharpLabel The Gotenberg approach requires a different endpoint (/forms/chromium/convert/url), building multipart content with the URL as a form field, and handling async HTTP responses. IronPDF's RenderUrlAsPdf() method accepts the URL directly and returns a PdfDocument object synchronously. Learn more about URL to PDF conversion. Example 3: Custom Paper Size and Margins Before (Gotenberg): using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergCustomSize { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); var html = "<html><body><h1>Custom Size PDF</h1></body></html>"; content.Add(new StringContent(html), "files", "index.html"); content.Add(new StringContent("8.5"), "paperWidth"); content.Add(new StringContent("11"), "paperHeight"); content.Add(new StringContent("0.5"), "marginTop"); content.Add(new StringContent("0.5"), "marginBottom"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes); Console.WriteLine("Custom size PDF generated successfully"); } } using System; using System.Net.Http; using System.Threading.Tasks; using System.IO; class GotenbergCustomSize { static async Task Main() { var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"; using var client = new HttpClient(); using var content = new MultipartFormDataContent(); var html = "<html><body><h1>Custom Size PDF</h1></body></html>"; content.Add(new StringContent(html), "files", "index.html"); content.Add(new StringContent("8.5"), "paperWidth"); content.Add(new StringContent("11"), "paperHeight"); content.Add(new StringContent("0.5"), "marginTop"); content.Add(new StringContent("0.5"), "marginBottom"); var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes); Console.WriteLine("Custom size PDF generated successfully"); } } $vbLabelText $csharpLabel After (IronPDF): // NuGet: Install-Package IronPdf using System; using IronPdf; using IronPdf.Rendering; class IronPdfCustomSize { static void Main() { var renderer = new ChromePdfRenderer(); renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter; renderer.RenderingOptions.MarginTop = 50; renderer.RenderingOptions.MarginBottom = 50; var html = "<html><body><h1>Custom Size PDF</h1></body></html>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("custom-size.pdf"); Console.WriteLine("Custom size PDF generated successfully"); } } // NuGet: Install-Package IronPdf using System; using IronPdf; using IronPdf.Rendering; class IronPdfCustomSize { static void Main() { var renderer = new ChromePdfRenderer(); renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter; renderer.RenderingOptions.MarginTop = 50; renderer.RenderingOptions.MarginBottom = 50; var html = "<html><body><h1>Custom Size PDF</h1></body></html>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("custom-size.pdf"); Console.WriteLine("Custom size PDF generated successfully"); } } $vbLabelText $csharpLabel Gotenberg requires string-based parameters ("8.5", "11", "0.5") added to multipart form data—no type safety, no IntelliSense, easy to mistype. IronPDF provides strongly-typed properties with PdfPaperSize enums and numeric margin values. Note that IronPDF margins are in millimeters (50mm ≈ 2 inches), while Gotenberg uses inches. Critical Migration Notes Unit Conversions The most important conversion in this Gotenberg migration is the margin units: // Gotenberg: margins in inches content.Add(new StringContent("0.5"), "marginTop"); // 0.5 inches content.Add(new StringContent("1"), "marginBottom"); // 1 inch // IronPDF: margins in millimeters renderer.RenderingOptions.MarginTop = 12.7; // 0.5 inches × 25.4 = 12.7mm renderer.RenderingOptions.MarginBottom = 25.4; // 1 inch × 25.4 = 25.4mm // Gotenberg: margins in inches content.Add(new StringContent("0.5"), "marginTop"); // 0.5 inches content.Add(new StringContent("1"), "marginBottom"); // 1 inch // IronPDF: margins in millimeters renderer.RenderingOptions.MarginTop = 12.7; // 0.5 inches × 25.4 = 12.7mm renderer.RenderingOptions.MarginBottom = 25.4; // 1 inch × 25.4 = 25.4mm $vbLabelText $csharpLabel Conversion formula: millimeters = inches × 25.4 Synchronous vs Asynchronous Gotenberg requires async operations because of HTTP communication: // Gotenberg: Forced async due to network calls var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); // IronPDF: Synchronous in-process execution var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("output.pdf"); // IronPDF: Async wrapper if needed var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(html)); // Gotenberg: Forced async due to network calls var response = await client.PostAsync(gotenbergUrl, content); var pdfBytes = await response.Content.ReadAsByteArrayAsync(); // IronPDF: Synchronous in-process execution var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("output.pdf"); // IronPDF: Async wrapper if needed var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(html)); $vbLabelText $csharpLabel Error Handling // Gotenberg: HTTP error handling try { var response = await client.PostAsync(gotenbergUrl, content); response.EnsureSuccessStatusCode(); // What if 500? 503? Timeout? } catch (HttpRequestException ex) { /* Network error */ } catch (TaskCanceledException ex) { /* Timeout */ } // IronPDF: Standard .NET exceptions try { var pdf = renderer.RenderHtmlAsPdf(html); } catch (Exception ex) { Console.WriteLine($"PDF generation failed: {ex.Message}"); } // Gotenberg: HTTP error handling try { var response = await client.PostAsync(gotenbergUrl, content); response.EnsureSuccessStatusCode(); // What if 500? 503? Timeout? } catch (HttpRequestException ex) { /* Network error */ } catch (TaskCanceledException ex) { /* Timeout */ } // IronPDF: Standard .NET exceptions try { var pdf = renderer.RenderHtmlAsPdf(html); } catch (Exception ex) { Console.WriteLine($"PDF generation failed: {ex.Message}"); } $vbLabelText $csharpLabel Infrastructure Removal After migration, remove Gotenberg from your infrastructure: # REMOVE from docker-compose.yml: # services: # gotenberg: # image: gotenberg/gotenberg:8 # ports: # - "3000:3000" # deploy: # resources: # limits: # memory: 2G # REMOVE from docker-compose.yml: # services: # gotenberg: # image: gotenberg/gotenberg:8 # ports: # - "3000:3000" # deploy: # resources: # limits: # memory: 2G YAML Performance Considerations Latency Comparison Operation Gotenberg (Warm) Gotenberg (Cold Start) IronPDF (First Render) IronPDF (Subsequent) Simple HTML 150-300ms 2-5 seconds 1-2 seconds 50-150ms Complex HTML 500-1500ms 3-7 seconds 1.5-3 seconds 200-800ms URL Render 1-5 seconds 3-10 seconds 1-5 seconds 500ms-3s Infrastructure Cost Elimination Resource Gotenberg IronPDF Containers required 1-N (scaling) 0 Memory per container 512MB-2GB N/A Network overhead per request 10-100ms 0ms Health check endpoints Required Not needed Load balancer Often needed Not needed Troubleshooting Issue 1: HttpClient Patterns Not Needed Problem: Code still using HttpClient and MultipartFormDataContent. Solution: Replace entirely with ChromePdfRenderer: // Remove all of this: // using var client = new HttpClient(); // using var content = new MultipartFormDataContent(); // content.Add(new StringContent(html), "files", "index.html"); // var response = await client.PostAsync(url, content); // Replace with: var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(html); // Remove all of this: // using var client = new HttpClient(); // using var content = new MultipartFormDataContent(); // content.Add(new StringContent(html), "files", "index.html"); // var response = await client.PostAsync(url, content); // Replace with: var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(html); $vbLabelText $csharpLabel Issue 2: Margin Units Wrong Problem: PDFs have incorrect margins after migration. Solution: Convert inches to millimeters: // Gotenberg used inches: "0.5" // IronPDF uses millimeters: 0.5 × 25.4 = 12.7 renderer.RenderingOptions.MarginTop = 12.7; // Gotenberg used inches: "0.5" // IronPDF uses millimeters: 0.5 × 25.4 = 12.7 renderer.RenderingOptions.MarginTop = 12.7; $vbLabelText $csharpLabel Issue 3: Container URL References Problem: Code contains http://gotenberg:3000 or similar URLs. Solution: Remove all container URL references—IronPDF runs in-process: // Remove: // private readonly string _gotenbergUrl = "http://gotenberg:3000"; // IronPDF needs no URL - it's in-process var renderer = new ChromePdfRenderer(); // Remove: // private readonly string _gotenbergUrl = "http://gotenberg:3000"; // IronPDF needs no URL - it's in-process var renderer = new ChromePdfRenderer(); $vbLabelText $csharpLabel Migration Checklist Pre-Migration Inventory all Gotenberg HTTP calls in codebase Document current Gotenberg configuration (timeouts, margins, paper sizes) Identify all Docker/Kubernetes Gotenberg configuration Obtain IronPDF license key Plan infrastructure decommissioning Code Migration Install IronPdf NuGet package: dotnet add package IronPdf Remove Gotenberg client packages Replace all HTTP calls to Gotenberg with IronPDF method calls Convert margin units from inches to millimeters Update error handling (HTTP errors → .NET exceptions) Add license key initialization at startup Infrastructure Migration Remove Gotenberg from Docker Compose / Kubernetes Update CI/CD pipelines (remove Gotenberg image pulls) Remove Gotenberg health checks Remove Gotenberg URL from configuration Testing Test HTML to PDF conversion Test URL to PDF conversion Verify margin and sizing accuracy Performance test under load Test first-render warmup time Post-Migration Remove Gotenberg container deployments Archive Gotenberg configuration files Update documentation Monitor application memory usage Verify no orphaned network connections 커티스 차우 지금 바로 엔지니어링 팀과 채팅하세요 기술 문서 작성자 커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다. 커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다. 관련 기사 게시됨 2월 1, 2026 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 더 읽어보기 게시됨 2월 1, 2026 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 더 읽어보기 게시됨 2월 1, 2026 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 더 읽어보기 How to Migrate from GrabzIt to IronPDF in C#How to Migrate from Gnostice PDFOne...
게시됨 2월 1, 2026 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 더 읽어보기
게시됨 2월 1, 2026 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 더 읽어보기
게시됨 2월 1, 2026 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 더 읽어보기