跳至页脚内容
迁移指南

如何用 C# 从 CraftMyPDF 迁移到 IronPDF

为什么要从CraftMyPDF迁移到 IronPDF?

基于云的 PDF API(如 CraftMyPDF)引入了一些基本问题,使其不适合许多生产环境。

基于云的 PDF API 的问题

1.您的数据离开您的系统:每个 HTML 模板和 JSON 数据有效负载都会传输到CraftMyPDF的服务器。 对于发票、合同、医疗记录或任何敏感的商业数据,这会产生 HIPAA、GDPR 和 SOC2 合规风险。

2.网络延迟:CraftMyPDF自己的文档指出,每个 PDF 需要 1.5-30 秒。IronPDF可在几毫秒内本地生成。

3.每个 PDF 的成本累积起来:每月 10,000 个 PDF 按订阅费率计算会产生大量的经常性成本,而一次性永久许可则不然。

4.针对打印优化的输出:云 API 通常会针对打印进行优化——减少背景并简化颜色以节省"墨水"。因此,最终输出结果与屏幕上显示的 HTML 代码看起来截然不同。

5.模板锁定:CraftMyPDF需要使用其专有的拖放式编辑器。 不能随意使用标准 HTML/CSS。

架构比较

方面 CraftMyPDF IronPDF
数据位置 云(您的数据离开您的系统) 内部部署(数据永不丢失)
延迟 1.每个 PDF 文件 5-30 秒 毫秒
定价 按 PDF 订阅 一次性永久许可
模板系统 仅限专有的拖放功能 任何 HTML/CSS/JavaScript
输出质量 印刷优化 像素完美的屏幕渲染
离线工作 否(需要互联网)
合规性 数据叶组织 符合 SOC2/HIPAA 标准

功能对比

特征 CraftMyPDF IronPDF
HTML 至 PDF 通过 API 模板 ✅ 本地
URL 至 PDF 通过 API ✅ 本地
自定义模板 仅限专有编辑器 ✅ 任何 HTML
支持 CSS3 有限的 ✅ 全文
JavaScript 渲染 有限的 ✅ 全文
合并/拆分 PDF 通过 API ✅ 本地
水印 通过 API ✅ 本地
离线工作
自托管

迁移前准备

前提条件

确保您的环境符合这些要求:

  • .NET Framework 4.6.2+ 或 .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ 或带有 C# 扩展的 VS Code
  • 访问 NuGet 包管理器 -IronPDF许可证密钥(可在ironpdf.com免费试用)

审核CraftMyPDF的使用情况

在解决方案目录中运行这些命令,以识别所有CraftMyPDF引用:

# Find allCraftMyPDFusages in your codebase
grep -r "CraftMyPdf\|craftmypdf\|api.craftmypdf.com" --include="*.cs" .
grep -r "X-API-KEY" --include="*.cs" .

# Find API key references
grep -r "your-api-key\|template-id\|template_id" --include="*.cs" .

# Find NuGet package references
grep -r "CraftMyPdf\|RestSharp" --include="*.csproj" .
# Find allCraftMyPDFusages in your codebase
grep -r "CraftMyPdf\|craftmypdf\|api.craftmypdf.com" --include="*.cs" .
grep -r "X-API-KEY" --include="*.cs" .

# Find API key references
grep -r "your-api-key\|template-id\|template_id" --include="*.cs" .

# Find NuGet package references
grep -r "CraftMyPdf\|RestSharp" --include="*.csproj" .
SHELL

值得期待的重大变化

变更 CraftMyPDF IronPDF 影响
架构 云 REST API 本地 .NET 库 删除 HTTP 调用
模板 专有编辑器 标准 HTML 将模板转换为 HTML
API关键字 每次通话都需要 启动时的许可 删除 API 密钥处理
同步模式 要求 (HTTP) 可选项 如果愿意,请删除等待
错误处理 HTTP 状态代码 例外情况 更改 try/catch 模式
数据绑定 JSON 模板 字符串插值 简化数据绑定

逐步迁移过程

步骤 1:更新 NuGet 软件包

移除 HTTP 客户端库并安装 IronPDF:

# Remove RestSharp HTTP client
dotnet remove package RestSharp

# Install IronPDF
dotnet add package IronPdf
# Remove RestSharp HTTP client
dotnet remove package RestSharp

# Install IronPDF
dotnet add package IronPdf
SHELL

步骤 2:更新命名空间引用

用IronPDF替换 HTTP 客户端命名空间:

// Remove these
using RestSharp;
using System.IO;

// Add this
using IronPdf;
// Remove these
using RestSharp;
using System.IO;

// Add this
using IronPdf;
$vbLabelText   $csharpLabel

步骤 3:配置许可证(启动时一次)

用单个许可证配置替换每次请求的 API 密钥头:

// Add at application startup (Program.cs or Global.asax)
// This replaces all X-API-KEY headers
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
// This replaces all X-API-KEY headers
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

完整的 API 迁移参考

API 端点映射

CraftMyPDF IronPDF 备注
POST /v1/create renderer.RenderHtmlAsPdf(html) 无需调用 API
X-API-KEY 标题 License.LicenseKey = "..." 启动时设置一次
模板id 标准 HTML 字符串 使用任何 HTML
{%name%} 占位符 $"{name}" C# 插值 标准 .NET
POST /v1/merge PdfDocument.Merge(pdfs) 本地即时翻译
POST /v1/add-watermark pdf.ApplyWatermark(html) 基于 HTML
Webhook 回调 不需要 结果同步
费率限制 不适用 无限制

配置映射

CraftMyPDF 选项 IronPdf 同等产品 备注
模板id HTML 字符串 使用您自己的 HTML
data JSON C# 插值 $"Hello {name}"
page_size:"A4" PaperSize = PdfPaperSize.A4
orientation:"横向" PaperOrientation = Landscape
margin_top: 20 MarginTop = 20 单位:毫米
标题 Html 标头 完全支持 HTML
footer HtmlFooter 完全支持 HTML

代码迁移示例

HTML 到 PDF 转换

最常见的操作演示了从云 API 到本地渲染的基本架构转变。

CraftMyPDF实现:

// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                html = "<h1>Hello World</h1><p>This is a PDF from HTML</p>"
            }
        });

        var response = client.Execute(request);
        File.WriteAllBytes("output.pdf", response.RawBytes);
    }
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                html = "<h1>Hello World</h1><p>This is a PDF from HTML</p>"
            }
        });

        var response = client.Execute(request);
        File.WriteAllBytes("output.pdf", response.RawBytes);
    }
}
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML</p>");
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

IronPdf 省去了 RestClient 设置、API key headers、模板 ID 和 HTTP 响应处理--将 15 行云操作减少到 4 行本地代码。 有关更多选项,请参阅 HTML 转 PDF 文档

URL到PDF转换

CraftMyPDF实现:

// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                url = "https://example.com"
            },
            export_type = "pdf"
        });

        var response = client.Execute(request);
        File.WriteAllBytes("webpage.pdf", response.RawBytes);
    }
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                url = "https://example.com"
            },
            export_type = "pdf"
        });

        var response = client.Execute(request);
        File.WriteAllBytes("webpage.pdf", response.RawBytes);
    }
}
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

IronPDF 的 RenderUrlAsPdf 方法可捕获完整的网页,包括 JavaScript 渲染的内容。 有关更多选项,请参阅 URL to PDF 文档

页眉和页脚

CraftMyPDF实现:

// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                html = "<h1>Document Content</h1>",
                header = "<div>Page Header</div>",
                footer = "<div>Page {page} of {total_pages}</div>"
            }
        });

        var response = client.Execute(request);
        File.WriteAllBytes("document.pdf", response.RawBytes);
    }
}
// NuGet: Install-Package RestSharp
using System;
using RestSharp;
using System.IO;

class Program
{
    static void Main()
    {
        var client = new RestClient("https://api.craftmypdf.com/v1/create");
        var request = new RestRequest(Method.POST);
        request.AddHeader("X-API-KEY", "your-api-key");
        request.AddJsonBody(new
        {
            template_id = "your-template-id",
            data = new
            {
                html = "<h1>Document Content</h1>",
                header = "<div>Page Header</div>",
                footer = "<div>Page {page} of {total_pages}</div>"
            }
        });

        var response = client.Execute(request);
        File.WriteAllBytes("document.pdf", response.RawBytes);
    }
}
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Page Header"
        };
        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page} of {total-pages}"
        };

        var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
        pdf.SaveAs("document.pdf");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Page Header"
        };
        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page} of {total-pages}"
        };

        var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
        pdf.SaveAs("document.pdf");
    }
}
$vbLabelText   $csharpLabel

IronPdf 支持占位符标记,如用于动态页码的 {page}{total-pages} 。 有关更多选项,请参阅页眉和页脚文档

模板变量转换

CraftMyPDF 使用专有模板占位符,必须将其转换为 C# 字符串插值:

CraftMyPDF模式:

//CraftMyPDFtemplate variables
request.AddJsonBody(new
{
    template_id = "invoice-template",
    data = new
    {
        customer = "John Doe",
        amount = "$1,000",
        items = invoiceItems
    }
});
//CraftMyPDFtemplate variables
request.AddJsonBody(new
{
    template_id = "invoice-template",
    data = new
    {
        customer = "John Doe",
        amount = "$1,000",
        items = invoiceItems
    }
});
$vbLabelText   $csharpLabel

IronPdf模式:

// C# string interpolation
var html = $@"
<html>
<body>
    <h1>Invoice</h1>
    <p>Customer: {customerName}</p>
    <p>Amount: {amount}</p>
    {GenerateItemsTable(invoiceItems)}
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(html);
// C# string interpolation
var html = $@"
<html>
<body>
    <h1>Invoice</h1>
    <p>Customer: {customerName}</p>
    <p>Amount: {amount}</p>
    {GenerateItemsTable(invoiceItems)}
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

关键迁移说明

删除所有 HTTP 代码

最重要的变化是消除了网络依赖性。IronPDF在本地运行--无 RestClient、无 API 调用、无响应处理:

//CraftMyPDF- HTTP required
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
var response = await client.ExecuteAsync(request);

//IronPDF- no HTTP
var pdf = renderer.RenderHtmlAsPdf(html);
//CraftMyPDF- HTTP required
var client = new RestClient("https://api.craftmypdf.com/v1/create");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "your-api-key");
var response = await client.ExecuteAsync(request);

//IronPDF- no HTTP
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

删除速率限制代码

CraftMyPDF 设置了 API 速率限制,需要重试逻辑。 IronPdf 没有限制:

//CraftMyPDF- needed to avoid 429 errors
await Task.Delay(100);
if (response.StatusCode == TooManyRequests) { /* retry */ }

//IronPDF- no limits, just generate
var pdf = renderer.RenderHtmlAsPdf(html);
// Remove all rate limit code!
//CraftMyPDF- needed to avoid 429 errors
await Task.Delay(100);
if (response.StatusCode == TooManyRequests) { /* retry */ }

//IronPDF- no limits, just generate
var pdf = renderer.RenderHtmlAsPdf(html);
// Remove all rate limit code!
$vbLabelText   $csharpLabel

删除 Webhook 处理程序

CraftMyPDF 使用异步网络钩子完成 PDF。IronPDF是同步的,PDF 可以立即完成:

//CraftMyPDF- webhook callback required
// POST with webhook_url, wait for callback

//IronPDF- PDF ready immediately
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No callback needed!
//CraftMyPDF- webhook callback required
// POST with webhook_url, wait for callback

//IronPDF- PDF ready immediately
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No callback needed!
$vbLabelText   $csharpLabel

默认同步

如果只需要在 HTTP 调用中使用 async/await 模式,则将其删除:

//CraftMyPDF- async required
var response = await client.ExecuteAsync(request);

//IronPDF- sync by default (async available if needed)
var pdf = renderer.RenderHtmlAsPdf(html);
//CraftMyPDF- async required
var response = await client.ExecuteAsync(request);

//IronPDF- sync by default (async available if needed)
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

迁移后核对表

完成代码迁移后,请验证以下内容:

  • 运行所有 PDF 生成测试
  • 比较输出质量(IronPDF 的 Chromium 引擎可实现像素级完美渲染)
  • 衡量性能提升(毫秒与秒)
  • 验证所有模板是否已正确转换
  • 测试无速率限制的批量处理
  • 在所有目标环境中进行测试
  • 更新 CI/CD 流水线 取消CraftMyPDF订阅
  • 从 secrets/config 中移除 API 密钥

未来保护您的 PDF 基础架构

随着 .NET 10 即将推出,C# 14 也将引入新的语言特性,选择本地 PDF 库可以消除云 API 过时风险和版本兼容性问题。IronPDF的永久许可模式意味着您的迁移投资将无限期地获得回报,因为项目将延伸到 2025 年和 2026 年--无需经常性订阅成本或数据离开您的基础架构。

其他资源


从CraftMyPDF迁移到IronPDF可以消除云依赖、网络延迟、每 PDF 成本和模板锁定,同时提供离线运行的像素级完美 Chromium 渲染。从 REST API 调用到本地方法调用的过渡简化了您的代码库,并将敏感文档数据保留在您的基础架构中。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。