
How to Add Stamps & Watermarks to PDFs in C#
GotenbergからIronPDFへの移行は、あなた for .NET PDFワークフローをHTTP API呼び出しによるDockerベースのマイクロサービス・アーキテクチャからプロセス内のネイティブC#ライブラリに変換します。 このガイドでは、.NETのプロフェッショナルな開発者向けに、インフラストラクチャのオーバーヘッド、ネットワーク遅延、コンテナ管理の複雑さを解消する、包括的でステップバイステップの移行パスを提供します。
なぜGotenbergからIronPDFに移行するのか
ゴテンベルク・アーキテクチャ問題
Gotenbergは、PDF生成のためのDockerベースのマイクロサービスアーキテクチャです。 強力で柔軟な反面、C#アプリケーションには大きな複雑さをもたらします:
1.インフラストラクチャのオーバーヘッド: Docker、コンテナ オーケストレーション (Kubernetes/Docker Compose)、サービス検出、負荷分散が必要です。 デプロイメントが複雑になるたびに
2.ネットワークレイテンシ: PDF操作ごとに別のサービスへのHTTP呼び出しが必要となり、リクエストごとに10~100ミリ秒以上の遅延が発生します。このレイテンシは、大量のデータを扱うシナリオでは急速に増大します。
3.コールド スタートの問題:コンテナーの起動により、最初のリクエストに 2 ~ 5 秒かかる場合があります。 ポッドの再起動、スケールアップのイベント、デプロイのたびにコールドスタートが発生します。
4.運用の複雑さ:コンテナの健全性、スケーリング、ログ記録、監視をメイン アプリケーションとは別の問題として管理する必要があります。
5.マルチパート フォーム データ:すべてのリクエストで、multipart/form-data ペイロードを構築する必要があります。これは冗長で、エラーが発生しやすく、保守が面倒です。
6.障害ポイント:ネットワーク タイムアウト、サービスの利用不可、コンテナのクラッシュはすべて、処理する責任があなたにあります。
7.**バージョン管理:**Gotenbergイメージはアプリケーションとは別に更新されます。 APIの変更は、予期せず統合を壊す可能性があります。
GotenbergとIronPDFの比較
| アスペクト | Gotenberg | IronPDF |
|---|---|---|
| デプロイメント | Dockerコンテナ+オーケストレーション | 単一のNuGetパッケージ |
| アーキテクチャ | マイクロサービス(REST API) | インプロセスライブラリ |
| リクエストあたりの待ち時間 | 10-100ms以上(ネットワーク・ラウンドトリップ) | <1msのオーバーヘッド |
| コールドスタート | 2~5秒(コンテナinit) | 1~2秒(最初のレンダリングのみ) |
| インフラ | Docker、Kubernetes、ロードバランサー | 不要 |
| 障害モード | ネットワーク、コンテナ、サービス障害 | .NET Standardの例外 |
| APIスタイル | REST multipart/form-data | C#ネイティブメソッドコール |
| スケーリング | 水平方向(コンテナを増やす) | 垂直方向(進行中) |
| デバッグ | 分散トレースが必要 | 標準デバッガ |
| バージョン管理 | コンテナ画像タグ | NuGetパッケージのバージョン |
現行 for .NETバージョンを対象とするチーム向けに、IronPDFはインフラ依存ゼロの基盤を提供し、現代 for .NETパターンにネイティブに統合します。
マイグレーションの複雑さの評価
機能別の見積もり作業
| フィーチャー | 移行の複雑さ |
|---|---|
| HTMLからPDFへ | 低レベル |
| URLからPDFへ | 低レベル |
| カスタム用紙サイズ | 低レベル |
| マージン | 低レベル |
| PDFマージ | 低レベル |
| ヘッダー/フッター | 中規模 |
| 待ち時間 | 低レベル |
| PDF/A変換 | 低レベル |
パラダイムシフト
このGotenberg移行における基本的な変化は、マルチパート フォーム データを使用した HTTP API 呼び出しからネイティブ C# メソッド呼び出しへの変更です。
Gotenberg: Docker コンテナへの HTTP POST multipart/form-data
IronPDF: C#オブジェクトの直接メソッド呼び出し
始める前に
前提条件
- .NETバージョン: IronPDFは.NET Framework 4.6.2以降および.NET Core 3.1以降 / .NET 5/6/7/8/9以降をサポートしています。 2.ライセンスキー: IronPDFからIronPDFライセンスキーを取得します。 3.インフラストラクチャの削除を計画する:移行後の廃止に向けてGotenbergコンテナを文書化する
すべてのGotenbergの使用法を特定する
# 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/KubernetesGotenbergconfiguration
grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" .
NuGetパッケージの変更
# RemoveGotenbergclient (if using)
dotnet remove package Gotenberg.Sharp.API.Client
# Install IronPDF
dotnet add package IronPdf
クイック スタート マイグレーション
ステップ 1: ライセンス構成の更新
ビフォア(Gotenberg):。
Gotenbergはライセンス不要ですが、コンテナURLのあるDockerインフラストラクチャが必要です。
private readonly string _gotenbergUrl = "http://localhost:3000";Private ReadOnly _gotenbergUrl As String = "http://localhost:3000"Private ReadOnly _gotenbergUrl As String = "http://localhost:3000"翻訳後(IronPDF):。
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";netnetステップ 2: 名前空間インポートを更新する
// 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;Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Imports IronPdf
Imports IronPdf.RenderingImports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Imports IronPdf
Imports IronPdf.Rendering完全な API リファレンス
GotenbergエンドポイントからIronPDFへのマッピング
| 御殿場ルート | IronPDF 同等物 |
|---|---|
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() の設定で |
GET /health | 該当なし |
フォーム パラメータと RenderingOptions のマッピング
| Gotenberg パラメータ | IronPDF プロパティ | 変換に関する注意事項 |
|---|---|---|
paperWidth(インチ) | RenderingOptions.PaperSize | 列挙型またはカスタムサイズを使用 |
paperHeight(インチ) | RenderingOptions.PaperSize | 列挙型またはカスタムサイズを使用 |
marginTop(インチ) | RenderingOptions.MarginTop | mmは25.4倍 |
marginBottom(インチ) | RenderingOptions.MarginBottom | mmは25.4倍 |
printBackground | RenderingOptions.PrintHtmlBackgrounds | ブーリアン |
landscape | RenderingOptions.PaperOrientation | Landscape enum |
"3s") | RenderingOptions.WaitFor.RenderDelay(ms) | 文字列をミリ秒に変換する |
コード移行の例
例1: 基本的なHTMLからPDFへ
ビフォア(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");
}
}Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Module GotenbergExample
Sub Main()
MainAsync().GetAwaiter().GetResult()
End Sub
Private Async Function MainAsync() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
Dim html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"
content.Add(New StringContent(html), "files", "index.html")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("output.pdf", pdfBytes)
Console.WriteLine("PDF generated successfully")
End Using
End Using
End Function
End ModuleImports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Module GotenbergExample
Sub Main()
MainAsync().GetAwaiter().GetResult()
End Sub
Private Async Function MainAsync() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
Dim html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"
content.Add(New StringContent(html), "files", "index.html")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("output.pdf", pdfBytes)
Console.WriteLine("PDF generated successfully")
End Using
End Using
End Function
End Module翻訳後(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");
}
}' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Module IronPdfExample
Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html = "<html><body><h1>Hello from IronPDF</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF generated successfully")
End Sub
End Module' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Module IronPdfExample
Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html = "<html><body><h1>Hello from IronPDF</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF generated successfully")
End Sub
End Module違いは大きいです:GotenbergではMultipartFormDataContentの構築、実行中のDockerコンテナへの非同期HTTP POST、およびバイト配列応答の処理が必要です。 IronPDFではChromePdfRendererメソッドコールでこれを3行に減らします - ネットワークの負荷なし、コンテナ依存なし、非同期の複雑さなし。 その他のレンダリングオプションについては、HTML to PDF documentationを参照してください。
例2: URLからPDFへの変換
ビフォア(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");
}
}Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Module GotenbergUrlToPdf
Async Function Main() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
content.Add(New StringContent("https://example.com"), "url")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("webpage.pdf", pdfBytes)
Console.WriteLine("PDF from URL generated successfully")
End Using
End Using
End Function
End ModuleImports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Module GotenbergUrlToPdf
Async Function Main() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
content.Add(New StringContent("https://example.com"), "url")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("webpage.pdf", pdfBytes)
Console.WriteLine("PDF from URL generated successfully")
End Using
End Using
End Function
End Module翻訳後(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");
}
}' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Class IronPdfUrlToPdf
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF from URL generated successfully")
End Sub
End Class' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Class IronPdfUrlToPdf
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF from URL generated successfully")
End Sub
End ClassGotenbergのアプローチでは別のエンドポイント(/forms/chromium/convert/url)、URLをフォームフィールドとするマルチパートコンテンツの構築、および非同期HTTP応答の処理が必要です。 IronPDFのPdfDocumentオブジェクトを同期的に返します。 URLからPDFへの変換の詳細については、こちらをご覧ください。
例3: カスタムの用紙サイズと余白
ビフォア(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");
}
}Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Class GotenbergCustomSize
Shared Async Function Main() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
Dim 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")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes)
Console.WriteLine("Custom size PDF generated successfully")
End Using
End Using
End Function
End ClassImports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO
Class GotenbergCustomSize
Shared Async Function Main() As Task
Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"
Using client As New HttpClient()
Using content As New MultipartFormDataContent()
Dim 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")
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
Await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes)
Console.WriteLine("Custom size PDF generated successfully")
End Using
End Using
End Function
End Class翻訳後(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");
}
}' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Rendering
Class IronPdfCustomSize
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 50
renderer.RenderingOptions.MarginBottom = 50
Dim html = "<html><body><h1>Custom Size PDF</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom-size.pdf")
Console.WriteLine("Custom size PDF generated successfully")
End Sub
End Class' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Rendering
Class IronPdfCustomSize
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 50
renderer.RenderingOptions.MarginBottom = 50
Dim html = "<html><body><h1>Custom Size PDF</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom-size.pdf")
Console.WriteLine("Custom size PDF generated successfully")
End Sub
End ClassGotenbergではマルチパートフォームデータに追加される文字列ベースのパラメータ("0.5")が必要です - 型の安全性なし、IntelliSenseなし、タイプミスしやすい。 IronPDFではPdfPaperSize enumと数値の余白値を持つ強く型付けされたプロパティを提供します。 IronPDFのマージンはミリメートル(50mm≈2インチ)ですが、Gotenbergはインチを使用していることに注意してください。
重要な移行に関する注意事項
単位変換
このGotenberg移行で最も重要な変換はマージン単位です:
// 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' 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変換式: millimeters = inches × 25.4
同期 vs 非同期
Gotenberg は HTTP 通信のため、非同期操作が必要です:
// 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));Imports System.Net.Http
' Gotenberg: Forced async due to network calls
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
' IronPDF: Synchronous in-process execution
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
' IronPDF: Async wrapper if needed
Dim pdf = Await Task.Run(Function() renderer.RenderHtmlAsPdf(html))Imports System.Net.Http
' Gotenberg: Forced async due to network calls
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
' IronPDF: Synchronous in-process execution
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
' IronPDF: Async wrapper if needed
Dim pdf = Await Task.Run(Function() renderer.RenderHtmlAsPdf(html))エラーハンドリング
// 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}");
}Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
' Gotenberg: HTTP error handling
Try
Dim response = Await client.PostAsync(gotenbergUrl, content)
response.EnsureSuccessStatusCode() ' What if 500? 503? Timeout?
Catch ex As HttpRequestException
' Network error
Catch ex As TaskCanceledException
' Timeout
End Try
' IronPDF: Standard .NET exceptions
Try
Dim pdf = renderer.RenderHtmlAsPdf(html)
Catch ex As Exception
Console.WriteLine($"PDF generation failed: {ex.Message}")
End TryImports System
Imports System.Net.Http
Imports System.Threading.Tasks
' Gotenberg: HTTP error handling
Try
Dim response = Await client.PostAsync(gotenbergUrl, content)
response.EnsureSuccessStatusCode() ' What if 500? 503? Timeout?
Catch ex As HttpRequestException
' Network error
Catch ex As TaskCanceledException
' Timeout
End Try
' IronPDF: Standard .NET exceptions
Try
Dim pdf = renderer.RenderHtmlAsPdf(html)
Catch ex As Exception
Console.WriteLine($"PDF generation failed: {ex.Message}")
End Tryインフラストラクチャの削除
移行後は、インフラストラクチャからGotenbergを削除してください:
# REMOVE from docker-compose.yml:
# services:
# gotenberg:
# image: gotenberg/gotenberg:8
# ports:
# - "3000:3000"
# deploy:
# resources:
# limits:
# memory: 2G
パフォーマンスの考慮事項
レイテンシーの比較
| 手術 | ゴテンベルク(暖かい) | Gotenberg(コールドスタート) | IronPDF (ファーストレンダリング) | IronPDF (後続) |
|---|---|---|---|---|
| シンプルなHTML | 150-300ms | 2~5秒 | 1~2秒 | 50-150ms |
| 複雑なHTML | 500-1500ms | 3~7秒 | 1.5-3秒 | 200-800ms |
| URLレンダー | 1~5秒 | 3~10秒 | 1~5秒 | 500ms-3s |
インフラストラクチャのコスト削減
| リソース | Gotenberg | IronPDF |
|---|---|---|
| 必要なコンテナ | 1-N (スケーリング) | 0 |
| コンテナあたりのメモリ | 512MB-2GB | 該当なし |
| リクエストあたりのネットワーク・オーバーヘッド | 10-100ms | 0ms |
| ヘルスチェックのエンドポイント | 必須 | 不要 |
| ロードバランサ | 多くの場合 | 不要 |
トラブルシューティング
問題 1: HttpClient パターンは必要ない
問題: コードは依然としてMultipartFormDataContentを使用しています。
解決策: 全て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);Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)課題2:マージンの単位が間違っている
問題:移行後、PDF の余白が正しくありません。
解決策:インチをミリメートルに変換する:
//Gotenbergused inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;//Gotenbergused inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;netnet課題3:コンテナURLリファレンス
問題: コードにはhttp://gotenberg:3000または類似のURLが含まれています。
解決策:すべてのコンテナ URL 参照を削除します(IronPDF はインプロセスで実行されます)。
// Remove:
// private readonly string _gotenbergUrl = "http://gotenberg:3000";
//IronPDFneeds no URL - it's in-process
var renderer = new ChromePdfRenderer();// Remove:
// private readonly string _gotenbergUrl = "http://gotenberg:3000";
//IronPDFneeds no URL - it's in-process
var renderer = new ChromePdfRenderer();netnet移行チェックリスト
移行前
- コードベース内のすべてのGotenberg HTTP呼び出しをインベントリする
- 現在のGotenberg構成 (タイムアウト、余白、用紙サイズ) を文書化します。
- すべてのDocker/Kubernetes Gotenberg構成を特定する
- IronPDFライセンスキーを取得する
- インフラの廃止を計画する
コードの移行
-IronPDFNuGetパッケージをインストールしてください: dotnet add package IronPdf
- Gotenbergクライアントパッケージを削除する
- GotenbergへのすべてのHTTP呼び出しをIronPDFメソッド呼び出しに置き換えます
- 余白の単位をインチからミリメートルに変換する
- エラー処理を更新 (HTTP エラー → .NET例外)
- 起動時にライセンスキーの初期化を追加
インフラストラクチャの移行
- Docker Compose / KubernetesからGotenbergを削除する
- CI/CD パイプラインを更新 (Gotenberg イメージ プルを削除)
- Gotenbergヘルスチェックを削除
- 設定からGotenberg URLを削除する
テスティング
- HTMLからPDFへの変換テスト
- URLからPDFへの変換テスト
- マージンとサイズの正確さを確認する
- 負荷テスト
- 最初のレンダリングのウォームアップ時間をテストする
移行後
- Gotenbergコンテナのデプロイメントを削除する -Gotenberg構成ファイルをアーカイブする
- ドキュメントの更新
- アプリケーションのメモリ使用量を監視する
- 孤立したネットワーク接続がないことを確認する
Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。
関連する記事


