跳過到頁腳內容
MIGRATION GUIDES

How to Migrate from WebView2 to IronPDF in C#

WebView2 是微軟的嵌入式 Edge/Chromium 瀏覽器控制項,它為開發者提供了一種在 Windows 應用程式中顯示 Web 內容的方法。 然而,當開發團隊嘗試使用 WebView2 產生 PDF 時,他們會遇到嚴重的架構限制,使其不適合生產環境。 WebView2 是一個專為 UI 應用程式設計的瀏覽器嵌入控件,而不是 PDF 生成庫。

本指南提供了從 WebView2 到 IronPDF 的完整遷移路徑,包括逐步說明、程式碼比較和實用範例,適用於需要在應用程式中可靠產生 PDF 的專業 .NET 開發人員。

重要警告:WebView2 不適用於產生 PDF 文件

在研究遷移路徑之前,開發團隊必須了解為什麼 WebView2 在用於建立 PDF 時會產生重大問題:

問題 影響 嚴重程度
內存洩漏 WebView2 在長時間運行的進程中存在有據可查的記憶體洩漏問題。 您的伺服器將會崩潰。 批判的
僅限 Windows 對 Linux、macOS、Docker 或雲端環境完全不支持 批判的
需要 UI 執行緒 必須在帶有訊息循環的 STA 線程上運行。無法在 Web 伺服器或 API 中使用。 批判的
並非為PDF設計 PrintToPdfAsync是事後新增的功能,並非核心功能。 高的
服務不穩定 Windows 服務和後台工作進程中經常出現崩潰和掛起的情況。 高的
複雜非同步流 導航事件、完成回調、競態條件 高的
邊緣運行時依賴項 需要在目標電腦上安裝 Edge WebView2 執行階段。 中等的
無頭模式 即使隱藏,也始終建立 UI 元素 中等的
表現 啟動緩慢,資源消耗高 中等的
缺乏專業支持 微軟不支援 PDF 產生用例 中等的

現實世界中的故障場景

這些程式碼模式會導致生產環境故障:

// DANGER: This code WILL cause problems in production

// 問題 1: Memory leak - creates new WebView2 for each PDF
public async Task<byte[]> GeneratePdf(string html) // Called 1000x/day = server crash
{
    using var webView = new WebView2(); // Memory not fully released!
    await webView.EnsureCoreWebView2Async();
    webView.CoreWebView2.NavigateToString(html);
    // ... memory accumulates until OOM
}

// 問題 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
    }
}
// DANGER: This code WILL cause problems in production

// 問題 1: Memory leak - creates new WebView2 for each PDF
public async Task<byte[]> GeneratePdf(string html) // Called 1000x/day = server crash
{
    using var webView = new WebView2(); // Memory not fully released!
    await webView.EnsureCoreWebView2Async();
    webView.CoreWebView2.NavigateToString(html);
    // ... memory accumulates until OOM
}

// 問題 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
    }
}
$vbLabelText   $csharpLabel

IronPDF 與 WebView2:功能對比

了解架構差異有助於技術決策者評估遷移投資:

方面 WebView2 IronPDF
目的 瀏覽器控制項(使用者介面) PDF庫(專為PDF設計)
生產就緒 是的
記憶體管理 長期運作中的洩漏 穩定,妥善處置
平台支援 僅限 Windows 系統 Windows、Linux、macOS、Docker
線程要求 STA + 資訊泵 任何貼文
伺服器/雲 不支援 全力支持
Azure/AWS/GCP 有問題的 完美運行
Docker 不可能 官方圖片已發布
ASP.NET Core 無法工作 一流的支持
背景服務 不穩定 穩定的
支援的上下文 僅限 WinForms/WPF 任何 .NET 環境:控制台、Web、桌面
HTML 轉 PDF 基本的 滿的
PDF檔案的URL 基本的 滿的
頁首/頁尾 是的(HTML)
水印 是的
合併PDF 是的
拆分PDF 是的
數位簽名 是的
密碼保護 是的
PDF/A 合規性 是的
專業支援 PDF 版本無 是的
文件 有限的 廣泛的

快速入門:WebView2 到 IronPDF 的遷移

透過這些基礎步驟,遷移工作可以立即開始。

步驟 1:移除 WebView2 套件

dotnet remove package Microsoft.Web.WebView2
dotnet remove package Microsoft.Web.WebView2
SHELL

或從項目文件中刪除:


<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />

<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />
XML

步驟 2:安裝 IronPDF

dotnet add package IronPdf
dotnet add package IronPdf
SHELL

步驟 3:更新命名空間

將 WebView2 命名空間替換為 IronPdf 命名空間:

// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;

// After (IronPDF)
using IronPdf;
// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;

// After (IronPDF)
using IronPdf;
$vbLabelText   $csharpLabel

步驟 4:初始化許可證

在應用程式啟動時新增許可證初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

程式碼遷移範例

將 HTML 轉換為 PDF

最基本的操作揭示了這些 .NET PDF 方法之間的複雜性差異。

WebView2 方法:

// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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);

        await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
            "Page.printToPDF",
            "{}"
        );
    }
}
// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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);

        await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
            "Page.printToPDF",
            "{}"
        );
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
// 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");
    }
}
$vbLabelText   $csharpLabel

WebView2 版本需要使用EnsureCoreWebView2Async()進行非同步初始化,透過NavigateToString()進行導航,使用不可靠的Task.Delay(2000)等待渲染,以及與 DevTools 協定互動。 IronPDF 完全省去了這一步驟——創建渲染器,渲染 HTML,保存。

如需更進階的 HTML 轉 PDF 場景,請參閱HTML 轉 PDF 轉換指南

將 URL 轉換為 PDF

URL 到 PDF 的轉換示範了 WebView2 複雜的非同步導航流程。

WebView2 方法:

// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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));
    }
}
// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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));
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
// 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");
    }
}
$vbLabelText   $csharpLabel

WebView2 需要建立TaskCompletionSource 、訂閱NavigationCompleted事件、呼叫CallDevToolsProtocolMethodAsync 、解析 JSON 回應以及解碼 base64 資料。 IronPDF 提供了一個專門的RenderUrlAsPdf方法,該方法在內部處理所有複雜性。

查看指向 PDF 文件的 URL ,以了解身份驗證和自訂標頭選項。

來自 HTML 文件的自訂 PDF 設定

配置頁面方向、頁邊距和紙張尺寸需要不同的方法。

WebView2 方法:

// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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);

        var printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
        printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
        printSettings.MarginTop = 0.5;
        printSettings.MarginBottom = 0.5;

        using (var stream = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings))
        {
            Console.WriteLine("Custom PDF created");
        }
    }
}
// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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);

        var printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
        printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
        printSettings.MarginTop = 0.5;
        printSettings.MarginBottom = 0.5;

        using (var stream = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings))
        {
            Console.WriteLine("Custom PDF created");
        }
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

// 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
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");
    }
}
$vbLabelText   $csharpLabel

WebView2 需要 3 秒的Task.Delay (一個不可靠的猜測),透過環境建立列印設置,並使用串流來呼叫PrintToPdfAsync 。 IronPDF 提供名稱清晰的直接RenderingOptions屬性,並使用毫米進行更精確的測量。

使用 DevTools 協定的高級 PDF 選項

複雜的 WebView2 配置需要 DevTools 協定互動。

WebView2 方法:

// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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));
    }
}
// NuGet: Install-Package Microsoft.Web.WebView2.WinForms
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));
    }
}
$vbLabelText   $csharpLabel

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
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");
    }
}
$vbLabelText   $csharpLabel

WebView2 需要建構匿名物件、序列化為 JSON、呼叫 DevTools 協定方法、解析 JSON 回應以及手動解碼 base64。 IronPDF 提供具有清晰名稱和枚舉值的類型化屬性,例如PdfPaperSize.Letter

WebView2 API 到 IronPDF 映射參考

此映射透過顯示直接的 API 等效項來加速遷移:

WebView2 API IronPDF當量 筆記
new WebView2() new ChromePdfRenderer() 無需使用者介面控件
EnsureCoreWebView2Async() 不適用 無需初始化
NavigateToString(html) + PrintToPdfAsync() RenderHtmlAsPdf(html) 單方法調用
Navigate(url) + PrintToPdfAsync() RenderUrlAsPdf(url) 單方法調用
PrintSettings.PageWidth RenderingOptions.PaperSize 使用 PdfPaperSize 列舉
PrintSettings.PageHeight RenderingOptions.PaperSize 使用 PdfPaperSize 列舉
PrintSettings.MarginTop RenderingOptions.MarginTop 單位是毫米,不是英寸
PrintSettings.Orientation RenderingOptions.PaperOrientation 人像/風景
ExecuteScriptAsync() HTML 中的 JavaScript 或使用 WaitFor 選項
AddScriptToExecuteOnDocumentCreatedAsync() HTML