解决 iText7 在 .NET MAUI 中的 Unknown PdfException
问题描述
在 .NET MAUI 应用程序中使用 iText7 生成 PDF 文件时,创建 PdfWriter
实例会引发以下异常:
Unknown PdfException -> System.NotSupportedException:
Either itext7.bouncy-castle-adapter or itext7.bouncy-castle-fips-adapter must be provided...
错误发生在以下代码行:
csharp
var writer = new PdfWriter(stream);
问题代码示例:
csharp
public static MemoryStream CreatePdf()
{
try
{
using (var stream = new MemoryStream())
{
var writer = new PdfWriter(stream); // 此处抛出异常
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
var paragraph = new Paragraph("hello");
document.Add(paragraph);
document.Close();
stream.Position = 0;
return stream;
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
此错误表明 iText7 无法加载必要的加密提供程序,导致 PDF 创建失败。
错误原因
此问题的根本原因源于 iText7 8.0 版本的重大变更:
- iText7 核心库移除了内置的 Bouncy Castle 加密依赖
- 开发者必须显式提供 Bouncy Castle 适配器
- .NET MAUI 环境没有自动解析此依赖关系
版本兼容性注意
此问题主要影响使用 iText7 8.0+ 版本 的项目,旧版本(7.x)不受影响
解决方案
✅ 推荐方案:安装 Bouncy Castle 适配器(标准修复)
通过 NuGet 添加以下必要包到你的 .NET MAUI 项目:
powershellInstall-Package itext7.bouncy-castle-adapter Install-Package Portable.BouncyCastle
确保版本兼容性:
itext7.bouncy-castle-adapter
版本应与 iText7 主包版本一致- 推荐的
Portable.BouncyCastle
版本:1.9.0+
安装验证
安装后检查项目的 .csproj
文件应包含以下引用:
xml
<PackageReference Include="itext7" Version="8.0.0+" />
<PackageReference Include="itext7.bouncy-castle-adapter" Version="8.0.0+" />
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
⚡ 替代方案:设置环境变量(特殊情况修复)
如果安装适配器后问题依然存在,可添加以下环境变量设置:
csharp
// 在 Program.cs 的 Maui 应用初始化代码中添加:
public static MauiApp CreateMauiApp()
{
// 关键配置:指定 Bouncy Castle 工厂
Environment.SetEnvironmentVariable("ITEXT_BOUNCY_CASTLE_FACTORY_NAME", "bouncy-castle");
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts => /* ... */);
return builder.Build();
}
重要提示
- 安装适配器后必须重启应用/开发环境(Visual Studio/Rider)
- 环境变量解决方案仅作为备用方案
- 此配置参考自 iText 官方文档
解决方案对比
方案 | 适用场景 | 优点 | 注意事项 |
---|---|---|---|
安装适配器包 | 多数情况 | 永久修复, 官方推荐 | 需要确保版本兼容性 |
设置环境变量 | 适配器安装后无效 | 快速验证方案 | 可能不兼容未来版本 |
完整工作代码
修复后可靠的 PDF 生成方法:
csharp
public static MemoryStream CreatePdf()
{
using var stream = new MemoryStream();
using var writer = new PdfWriter(stream);
using var pdf = new PdfDocument(writer);
using var document = new Document(pdf);
document.Add(new Paragraph("Hello MAUI with iText7"));
// 关闭文档(会自动关闭底层资源)
document.Close();
stream.Position = 0;
return stream;
}
技术原理
iText7 8.0+ 的模块化架构变更:
解决方案的作用:
itext7.bouncy-castle-adapter
:提供加密功能的桥接层Portable.BouncyCastle
:实际密码学算法实现- 环境变量:明确指定使用的密码学提供程序
版本兼容建议
iText7 版本 | 推荐操作 |
---|---|
7.x | 无需适配器 |
8.0-8.0.3 | 安装适配器 + Portable.BouncyCastle 1.8.1+ |
8.0.4+ | 安装适配器 + Portable.BouncyCastle 1.9.0+ |
避免使用过时依赖
不要混合使用不同版本的 iText 组件,这会导致难以诊断的兼容性问题