C#でPDFをサニタイズする方法 | IronPDF
WebView2、Microsoft の組み込み可能な Edge/Chromium ブラウザーコントロール (Microsoft.Web.WebView2) は、開発者に Windows アプリケーション内でウェブコンテンツを表示する方法を提供します。 しかし、開発チームがWebView2をPDF生成に使用しようとすると、ヘッドレスやサーバーのシナリオに適さない建築上の制限に直面します。 WebView2はPDF生成ライブラリではなく、UIアプリケーション用に設計されたブラウザ組み込みコントロールです。
このガイドはWebView2からIronPDFへの移行パスを提供し、コードの比較と.NET開発者がアプリケーションで信頼できるPDF生成を必要とする場合の実用的な例を示します。
WebView2がPDF生成に不適切な理由
移行パスを調べる前に、WebView2がヘッドレスPDF作成に不適している理由を理解するのに役立ちます:
| 課題 | インパクト | 重要度 |
|---|---|---|
| メモリリーク | WebView2インスタンスを繰り返し生成する長時間実行されるプロセス中に報告されるメモリ増加。 | 高 |
| Windowsのみ。 | Linux、macOS、Docker、または非Windowsクラウド環境のサポートなし | 重要 |
| UIスレッドが必要です。 | メッセージポンプを備えたSTAスレッドで実行する必要があります。WebサーバーやバックグラウンドAPIには適していません。 | 重要 |
| PDF用にデザインされていません。 | PrintToPdfAsync はサブ機能であり、コア機能ではありません | 高 |
| 不安定なサービス | Windowsサービスやバックグラウンドワーカーで報告されるクラッシュとハング | 高 |
| 複雑な非同期フロー | ナビゲーションイベント、完了コールバック、レースコンディション | 高 |
| エッジランタイム依存関係 | ターゲットマシンにEdge WebView2ランタイムがインストールされていることが要求されます。 | 中級 |
| ヘッドレスモードはありません。 | UIコントロールを基盤にして設計されています; ヘッドレスレンダラーではありません | 中級 |
| パフォーマンス | 起動が遅く、リソースの消費が激しい | 中級 |
| PDFサポートストーリーなし | MicrosoftはWebView2をPDF生成製品として位置付けていません | 中級 |
現実世界の失敗シナリオ
これらのコードパターンにより、プロダクションで問題が発生することが一般的です:
// WARNING: These patterns are known to cause problems in headless / server scenarios
//課題1: Memory growth - creates a newWebView2per PDF
public async Task<byte[]> GeneratePdf(string html) // High call volume accumulates memory
{
using var webView = new WebView2(); // Disposal does not fully reclaim native resources
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString(html);
// ... memory growth reported over time
}
//課題2: UI thread requirement - crashes in ASP.NET
public IActionResult GenerateReport() // FAILS - no STA thread
{
var webView = new WebView2(); // InvalidOperationException
}
//課題3: Windows Service instability
public class PdfService : BackgroundService // Random crashes
{
protected override async Task ExecuteAsync(CancellationToken token)
{
//WebView2+ no message pump = hangs, crashes, undefined behavior
}
}
IronPDFとWebView2の比較: 機能の比較
アーキテクチャの違いを理解することは、技術的な意思決定者が移行への投資を評価するのに役立ちます:
| アスペクト | WebView2 | IronPDF |
|---|---|---|
| 目的 | ブラウザコントロール(UI) | PDFライブラリ(PDF用に設計) |
| プロダクションレディ | NO | はい |
| メモリ管理 | 長時間実行プロセス中に報告されるメモリ増加 | 安定した適切な処理 |
| プラットフォームサポート | Windowsのみ | Windows、Linux、macOS、Docker |
| スレッドの要件 | STA + メッセージポンプ | スレッド |
| サーバー/クラウド | サポートされていません | サポート対象 |
| Azure/AWS/GCP(アジュール/AWS/GCP | 問題点 | 完璧な翻訳 |
| Docker。 | 不可 | 利用可能な公式画像 |
| .NETコア。 | 不可 | 一流のサポート |
| バックグラウンドサービス | 不安定 | 安定性 |
| サポートされるコンテキスト | WinForms/WPFのみ | あらゆる.NETコンテキスト:コンソール、ウェブ、デスクトップ |
| HTMLからPDFへ | 基本 | フル |
| URLからPDFへ。 | 基本 | フル |
| ヘッダー/フッター | NO | はい(HTML) |
| ウォーターマーク。 | NO | はい |
| PDFをマージする。 | NO | はい |
| PDFを分割する。 | NO | はい |
| デジタル署名。 | NO | はい |
| パスワード保護 | NO | はい |
| PDF/Aコンプライアンス | NO | はい |
| プロフェッショナルサポート | PDFはありません | はい |
| ドキュメント | 制限的 | 広範囲 |
クイックスタートWebView2からIronPDFへの移行
これらの基本的なステップを踏めば、すぐにでも移行を開始できます。
ステップ 1:WebView2パッケージの削除
dotnet remove package Microsoft.Web.WebView2
または、プロジェクトファイルから削除してください:
<!-- REMOVE these packages -->
<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />
ステップ2: IronPDFをインストールする
ステップ 3: 名前空間の更新
WebView2の名前空間をIronPDFの名前空間と置き換えます:
// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
// After (IronPDF)
using IronPdf;Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
' After (IronPDF)
Imports IronPdfステップ 4: ライセンスの初期化
アプリケーション起動時のライセンス初期化を追加します:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"コード移行の例
HTML を PDF に変換する
最も基本的な操作は、これら for .NET PDFアプローチの複雑さの違いを明らかにします。
WebView2のアプローチ:
// NuGet: Install-Package Microsoft.Web.WebView2
// (the WinForms host lives in the same package; no separate .WinForms package)
// Requires the EdgeWebView2Runtime installed on the target machine. Windows-only.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString("<html><body><h1>Hello World</h1></body></html>");
await Task.Delay(2000);
// PrintToPdfAsync(path, settings) returns Task<bool>; null = default settings
bool ok = await webView.CoreWebView2.PrintToPdfAsync("output.pdf", null);
}
}
IronPDFのアプローチ:
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>")
pdf.SaveAs("output.pdf")
End Sub
End ClassWebView2 バージョンでは、EnsureCoreWebView2Async() を使用した非同期初期化、NavigateToString() を介したナビゲーション、レンダリングを待つための Task.Delay(2000)、そして成功を示す Task<bool> を返す最終的な PrintToPdfAsync呼び出しが必要です。 IronPDFはこの儀式を排除します—レンダラーを作成し、HTMLをレンダリングし、保存します。
高度なHTMLからPDFへのシナリオについては、HTMLからPDFへの変換ガイドをご覧ください。
URLをPDFに変換する
URLからPDFへの変換は、WebView2の複雑な非同期ナビゲーションフローを示しています。
WebView2のアプローチ:
// NuGet: Install-Package Microsoft.Web.WebView2
// (Edge Chromium control; requires EdgeWebView2Runtime; Windows-only.)
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate("https://example.com");
await tcs.Task;
await Task.Delay(1000);
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
"{\"printBackground\": true}"
);
var base64 = System.Text.Json.JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
IronPDFのアプローチ:
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("output.pdf")
End Sub
End ClassWebView2 は、TaskCompletionSource の作成、NavigationCompleted イベントの登録、CallDevToolsProtocolMethodAsync の呼び出し、JSON 応答の解析、および base64 データのデコードを必要とします。IronPDFはすべての複雑さを内部で処理する専用の RenderUrlAsPdf メソッドを提供します。
認証とカスタムヘッダーオプションについては、URL to PDF documentationを参照してください。
HTMLファイルからのカスタムPDF設定
ページの向き、余白、用紙サイズの設定には、さまざまなアプローチが必要です。
WebView2のアプローチ:
// NuGet: Install-Package Microsoft.Web.WebView2
// CreatePrintSettings() lives on CoreWebView2Environment.
// Margin* / PageWidth / PageHeight on CoreWebView2PrintSettings are in INCHES.
// PrintToPdfAsync(path, settings) returns Task<bool> (true on success) — not a stream.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
webView.CoreWebView2.Navigate(htmlFile);
await Task.Delay(3000);
CoreWebView2PrintSettings printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
printSettings.MarginTop = 0.5; // inches
printSettings.MarginBottom = 0.5; // inches
printSettings.ShouldPrintBackgrounds = true;
bool ok = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings);
Console.WriteLine(ok ? "Custom PDF created" : "PrintToPdfAsync returned false");
}
}Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
Module Program
Async Function Main() As Task
Dim webView As New WebView2()
Await webView.EnsureCoreWebView2Async()
Dim htmlFile As String = Path.Combine(Directory.GetCurrentDirectory(), "input.html")
webView.CoreWebView2.Navigate(htmlFile)
Await Task.Delay(3000)
Dim printSettings As CoreWebView2PrintSettings = webView.CoreWebView2.Environment.CreatePrintSettings()
printSettings.Orientation = CoreWebView2PrintOrientation.Landscape
printSettings.MarginTop = 0.5 ' inches
printSettings.MarginBottom = 0.5 ' inches
printSettings.ShouldPrintBackgrounds = True
Dim ok As Boolean = Await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings)
Console.WriteLine(If(ok, "Custom PDF created", "PrintToPdfAsync returned false"))
End Function
End ModuleIronPDFのアプローチ:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
var pdf = renderer.RenderHtmlFileAsPdf(htmlFile);
pdf.SaveAs("custom.pdf");
Console.WriteLine("Custom PDF created");
}
}' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Imports System.IO
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 50
renderer.RenderingOptions.MarginBottom = 50
Dim htmlFile As String = Path.Combine(Directory.GetCurrentDirectory(), "input.html")
Dim pdf = renderer.RenderHtmlFileAsPdf(htmlFile)
pdf.SaveAs("custom.pdf")
Console.WriteLine("Custom PDF created")
End Sub
End ModuleWebView2 には 3 秒の Task.Delay (信頼性の低い推測)、CoreWebView2.Environment を通じた印刷設定の作成、およびストリームではなく Task<bool> を返す PrintToPdfAsync(path, settings) の await が必要です。 WebView2はマージンをインチで表現します;IronPDFはミリメートルを直接 RenderingOptions プロパティで使用します。
DevToolsプロトコルによる高度なPDFオプション
複雑なWebView2の設定には、DevToolsプロトコルの対話が必要です。
WebView2のアプローチ:
// NuGet: Install-Package Microsoft.Web.WebView2
// Uses raw Chrome DevTools Protocol via CallDevToolsProtocolMethodAsync.
// (Page.printToPDF returns base64 in result.data; units are inches.)
using System;
using System.IO;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var htmlPath = Path.GetFullPath("document.html");
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate($"file:///{htmlPath}");
await tcs.Task;
await Task.Delay(1000);
var options = new
{
landscape = false,
printBackground = true,
paperWidth = 8.5,
paperHeight = 11,
marginTop = 0.4,
marginBottom = 0.4,
marginLeft = 0.4,
marginRight = 0.4
};
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
JsonSerializer.Serialize(options)
);
var base64 = JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
IronPDFのアプローチ:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.MarginLeft = 40;
renderer.RenderingOptions.MarginRight = 40;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
var pdf = renderer.RenderHtmlFileAsPdf("document.html");
pdf.SaveAs("output.pdf");
}
}' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronPdf.Rendering
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 40
renderer.RenderingOptions.MarginBottom = 40
renderer.RenderingOptions.MarginLeft = 40
renderer.RenderingOptions.MarginRight = 40
renderer.RenderingOptions.PrintHtmlBackgrounds = True
Dim pdf = renderer.RenderHtmlFileAsPdf("document.html")
pdf.SaveAs("output.pdf")
End Sub
End ModuleWebView2 では、匿名オブジェクトの構築、JSON へのシリアル化、DevTools Protocol メソッドの呼び出し、JSON 応答の解析、および base64 の手動デコードが必要ですが、IronPDF は PdfPaperSize.Letter のような明確な名前と列挙値を持つ型付きプロパティを提供します。
##WebView2APIからIronPDFへのマッピングリファレンス
このマッピングは、APIと同等のものを直接示すことで、移行を加速します:
| WebView2 API | IronPDF 同等物 |
|---|---|
new WebView2() | new ChromePdfRenderer() |
EnsureCoreWebView2Async() | 該当なし |
NavigateToString(html) + PrintToPdfAsync() | RenderHtmlAsPdf(html) |
Navigate(url) + PrintToPdfAsync() | RenderUrlAsPdf(url) |
PrintSettings.PageWidth | RenderingOptions.PaperSize |
PrintSettings.PageHeight | RenderingOptions.PaperSize |
PrintSettings.MarginTop | RenderingOptions.MarginTop |
PrintSettings.Orientation | RenderingOptions.PaperOrientation |
ExecuteScriptAsync() | HTML for JavaScript |
AddScriptToExecuteOnDocumentCreatedAsync() | HTML <script> タグ |
| ナビゲーションイベント | WaitFor.JavaScript() |
CallDevToolsProtocolMethodAsync("Page.printToPDF") | RenderHtmlAsPdf() |
一般的な移行の問題と解決策
問題1: メモリ増加
WebView2 問題: メモリ増加は、メッセージポンプが安定していない場合、特にWebView2インスタンスを繰り返し生成する場合に長時間実行プロセスで報告されます。
IronPDF ソリューション: 予測可能なディスポーザルと using に優しいライフサイクル:
//IronPDF- clean memory management
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
} // Properly disposedImports IronPdf
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Using課題2:ウェブアプリにUIスレッドがない
WebView2の問題 メッセージポンプを備えたSTAスレッドが必要です。.NET Core コントローラーはWebView2インスタンスを作成できません。
**IronPDFソリューション:**どのスレッドでも動作します:
// ASP.NET Core - just works
public async Task<IActionResult> GetPdf()
{
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class YourController
Inherits Controller
Public Async Function GetPdf() As Task(Of IActionResult)
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Function
End Class課題3:ナビゲーションイベントの複雑さ
WebView2 の問題: 非同期ナビゲーションイベント、完了コールバック、および TaskCompletionSource を使用した競合状態を処理する必要があります。
IronPDFソリューション: 同期または非同期の単一メソッド呼び出し:
// Simple and predictable
var pdf = renderer.RenderHtmlAsPdf(html);
// or
var pdf = await renderer.RenderHtmlAsPdfAsync(html);net課題4:測定単位
WebView2は寸法にインチを使用しています(レターは8.5 x 11)。 IronPDFは、より正確な測定のためにミリメートルを使用しています。
変換アプローチ:。
// WebView2: PageWidth = 8.27 (inches for A4)
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297);' WebView2: PageWidth = 8.27 (inches for A4)
' IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
' Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297)WebView2移行のチェックリスト
マイグレーション前のタスク
コードベース内のすべてのWebView2PDF 生成コードを文書化します。WebView2が問題(メモリリーク、クラッシュ、デプロイの問題)を引き起こしている箇所を特定すること。 IronPDFのドキュメントを見て、機能を理解してください。
コード更新タスク
1.Microsoft.Web.WebView2 NuGet パッケージの削除
2.IronPDFNuGet パッケージをインストールします
3.PDF生成にのみ使用する場合は、WinForms/WPFの依存関係を削除してください。
4.WebView2コードを ChromePdfRenderer に置き換えます
5.STAスレッド要件の削除
6. ナビゲーションイベントハンドラと TaskCompletionSource パターンを削除します
7. Task.Delayのハックを削除します
8.起動時にIronPDFライセンスの初期化を追加する
移行後のテスト
移行後、これらの点を検証してください:
- ターゲット環境でのテスト(ASP.NET、Docker、該当する場合はLinux)
- PDF出力の品質が期待値に合っていることを確認
- JavaScriptを多用したページが正しくレンダリングされることをテストする
- ヘッダーとフッターがIronPDFのHTML機能で動作することを確認する。
- 長時間の動作におけるメモリの安定性に関する負荷テスト
- メモリの蓄積なしに長時間実行するシナリオをテストする
デプロイメントの更新
- 該当する場合は、Dockerイメージを更新してください(EdgeWebView2Runtimeを削除してください)。
- サーバー要件からEdgeWebView2Runtimeの依存関係を削除する
- サーバー要件ドキュメントの更新
- クロスプラットフォーム展開がターゲットプラットフォームで動作することを確認する。
WebView2は、その関連する所有者の登録商標です。 このサイトは、マイクロソフトと提携しているわけでも、マイクロソフトが推奨しているわけでも、マイクロソフトがスポンサーしているわけでもありません。 すべての製品名、ロゴ、およびブランドは各所有者の所有物です。 比較は情報提供のみを目的としており、執筆時点で公開されている情報を反映しています。)}]

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。