如何使用IronPDF创建.NET PDF API
在使用现代应用程序时,像您这样的.NET开发人员可能会发现需要构建一个集中的PDF生成服务。无论您是生成发票、报告、证书或合同,拥有一个专门的.NET PDF API对于高效管理PDF文件都是有益的。 那么它如何改善您的PDF生成任务呢? 它通过在桌面和Web应用程序之间提供一致性、可维护性和可扩展性来实现这一点。 从未有过如此轻松地管理文档内容、PDF页面和PDF表单字段。
在本教程中,您将学习如何使用ASP.NET Core和IronPDF,一个强大的.NET PDF库,构建一个可用于生产的PDF API。 我们将创建可以从HTML生成PDF、合并文档、添加水印并处理Web API中各种实际PDF生成场景的RESTful端点。
为什么构建一个专门的PDF API?
在深入研究代码之前,让我们了解为什么创建一个专门的PDF API是有意义的:
- 集中化逻辑:所有的PDF生成逻辑都集中在一个地方,使得维护和更新更加容易
- 微服务架构:对于需要PDF功能的不同应用程序的面向服务架构来说是完美的
- 性能优化:更容易为大型PDF文件、多页面和动态数据优化和扩展专用服务。
- 语言无关:任何客户端应用程序都可以消费该API,无论编程语言如何
- 输出一致性:确保整个组织的所有PDF文档都保持一致的文档布局、段落格式和PDF内容。
准备好开始构建了吗? 下载IronPDF的免费试用版,并按此教程一起编程实现.NET Framework项目中的PDF文件创建。
IronPDF: 完整的.NET PDF库
IronPDF被认为是.NET开发人员的首选PDF库,提供了一套全面的功能,使Web API项目中的PDF生成过程简单可靠。 它建立在Chrome渲染引擎上,确保像素级精准的HTML到PDF转换,通常只需几行代码即可完成。 这在保持所有样式、JavaScript执行和响应布局的同时完成。
使IronPDF成为.NET PDF API开发的理想选择的关键能力有:
如何设置您的PDF文档API项目?
让我们从创建一个新的ASP.NET Core Web API项目并安装必要的包开始。
前提条件
- .NET 6.0 SDK或更高版本
- Visual Studio 2022或Visual Studio Code
- Postman或类似的API测试工具,以测试您的PDF REST API
创建项目
首先,让我们创建一个项目,我们将在其中构建我们的PDF生成工具。
dotnet new webapi -n PdfApiService
cd PdfApiService安装 IronPDF。
下一步是通过NuGet将IronPDF添加到您的项目中:
dotnet add package IronPdf或者,在Visual Studio中使用NuGet包管理器控制台:
Install-Package IronPdf
项目结构
C#开发的一个重要方面是保持一个干净且结构良好的项目文件夹。 例如:
如何创建您的第一个PDF端点?
让我们构建一个简单的端点,将HTML转换为PDF格式。 首先,创建服务接口和实现:
创建PDF服务
首先,我们将在我们的IPdfService.cs文件中添加以下内容:
public interface IPdfService
{
byte[] GeneratePdfFromHtml(string htmlContent);
byte[] GeneratePdfFromUrl(string url);
}public interface IPdfService
{
byte[] GeneratePdfFromHtml(string htmlContent);
byte[] GeneratePdfFromUrl(string url);
}IRON VB CONVERTER ERROR developers@ironsoftware.com在PdfService.cs文件中,我们将添加:
using IronPdf;
public class PdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public PdfService()
{
_renderer = new ChromePdfRenderer();
// Configure rendering options for optimal PDF generation in .NET
_renderer.RenderingOptions.MarginTop = 20;
_renderer.RenderingOptions.MarginBottom = 20;
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
}
public byte[] GeneratePdfFromHtml(string htmlContent)
{
// Generate PDF from HTML using the .NET PDF API
var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
return pdf.BinaryData;
}
public byte[] GeneratePdfFromUrl(string url)
{
// Convert URL to PDF in the REST API
var pdf = _renderer.RenderUrlAsPdf(url);
return pdf.BinaryData;
}
}using IronPdf;
public class PdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public PdfService()
{
_renderer = new ChromePdfRenderer();
// Configure rendering options for optimal PDF generation in .NET
_renderer.RenderingOptions.MarginTop = 20;
_renderer.RenderingOptions.MarginBottom = 20;
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
}
public byte[] GeneratePdfFromHtml(string htmlContent)
{
// Generate PDF from HTML using the .NET PDF API
var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
return pdf.BinaryData;
}
public byte[] GeneratePdfFromUrl(string url)
{
// Convert URL to PDF in the REST API
var pdf = _renderer.RenderUrlAsPdf(url);
return pdf.BinaryData;
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comPdfService处理将HTML转换为PDF的核心过程。 利用IronPDF的ChromePdfRenderer,此类设置了合理的默认值,如页面边距和背景渲染,以生成一个精美的最终文档。
当控制器传递原始HTML时,服务使用IronPDF将其呈现为专业质量的PDF,并将结果返回为字节数据,准备好下载。 此外,它还可以通过将URL直接转换为PDF来处理整个网页。
创建控制器
现在是为我们的API创建控制器的时间了。 这将提供一个可以从HTML生成PDF文件的API端点。 然后,能够下载并将PDF文档保存到您的系统中,以便进一步使用或共享。
// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
private readonly IPdfService _pdfService;
public PdfController(IPdfService pdfService)
{
_pdfService = pdfService;
}
[HttpPost("html-to-pdf")]
public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
{
try
{
var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
// Return as downloadable file
return File(pdfBytes, "application/pdf", "document.pdf");
}
catch (Exception ex)
{
return BadRequest($"Error generating PDF: {ex.Message}");
}
}
}// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
private readonly IPdfService _pdfService;
public PdfController(IPdfService pdfService)
{
_pdfService = pdfService;
}
[HttpPost("html-to-pdf")]
public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
{
try
{
var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
// Return as downloadable file
return File(pdfBytes, "application/pdf", "document.pdf");
}
catch (Exception ex)
{
return BadRequest($"Error generating PDF: {ex.Message}");
}
}
}IRON VB CONVERTER ERROR developers@ironsoftware.com然后,在HtmlRequest.cs文件中,我们将添加:
// Models/HtmlRequest.cs
public class HtmlRequest
{
public string HtmlContent { get; set; }
public string FileName { get; set; } = "document.pdf";
}// Models/HtmlRequest.cs
public class HtmlRequest
{
public string HtmlContent { get; set; }
public string FileName { get; set; } = "document.pdf";
}IRON VB CONVERTER ERROR developers@ironsoftware.com在第一个文件中,我们设置了一个简单的API端点,将HTML转换为可下载的PDF。 当有人通过简单的POST请求将HTML内容发送到api/pdf/html-to-pdf路由时,PdfController将任务传递给专用的服务,将其转换为PDF。
一旦PDF创建完成,控制器将它作为一个准备好下载的文件返回给用户。请求本身是使用HtmlRequest模型结构化的,该模型携带原始HTML和用于最终文档的可选文件名。 简而言之,此设置使得客户端可以轻松发送HTML并立即获得一个精美的PDF作为返回。
注册服务
更新您的Program.cs以注册PDF服务:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();IRON VB CONVERTER ERROR developers@ironsoftware.com如何处理不同的响应类型?
您的API应该支持基于客户端需求以不同方式返回PDF:
[HttpPost("generate")]
public IActionResult GeneratePdf([FromBody] PdfRequest request)
{
var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
switch (request.ResponseType?.ToLower())
{
case "base64":
return Ok(new
{
data = Convert.ToBase64String(pdfBytes),
filename = request.FileName
});
case "inline":
return File(pdfBytes, "application/pdf");
default: // download
return File(pdfBytes, "application/pdf", request.FileName);
}
}[HttpPost("generate")]
public IActionResult GeneratePdf([FromBody] PdfRequest request)
{
var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
switch (request.ResponseType?.ToLower())
{
case "base64":
return Ok(new
{
data = Convert.ToBase64String(pdfBytes),
filename = request.FileName
});
case "inline":
return File(pdfBytes, "application/pdf");
default: // download
return File(pdfBytes, "application/pdf", request.FileName);
}
}IRON VB CONVERTER ERROR developers@ironsoftware.com在这里,我们在控制器中添加了一个更灵活的PDF生成端点。 而不是总是强制下载文件,GeneratePdf方法让客户端选择他们希望结果如何返回。 此选项提供灵活性,允许PDF以多种格式显示:作为可下载文件,直接在浏览器中,或编码为Base64字符串以便在API中轻松使用。
请求由PdfRequest模型定义,该模型基于之前的HtmlRequest,并添加一个ResponseType选项。 总之,这使用户能够更好地控制如何接收他们的PDF,使API更加多样化和用户友好。
现在,当我们运行程序时,我们将在Swagger上看到此输出。

如何实现常见的PDF操作?
让我们扩展我们的服务以处理各种PDF生成场景:
URL到PDF转换
[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
try
{
var pdfBytes = await Task.Run(() =>
_pdfService.GeneratePdfFromUrl(request.Url));
return File(pdfBytes, "application/pdf",
$"{request.FileName ?? "website"}.pdf");
}
catch (Exception ex)
{
return BadRequest($"Failed to convert URL: {ex.Message}");
}
}
public class UrlRequest
{
public string Url { get; set; }
public string FileName { get; set; }
}[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
try
{
var pdfBytes = await Task.Run(() =>
_pdfService.GeneratePdfFromUrl(request.Url));
return File(pdfBytes, "application/pdf",
$"{request.FileName ?? "website"}.pdf");
}
catch (Exception ex)
{
return BadRequest($"Failed to convert URL: {ex.Message}");
}
}
public class UrlRequest
{
public string Url { get; set; }
public string FileName { get; set; }
}IRON VB CONVERTER ERROR developers@ironsoftware.com此端点允许客户端发送一个URL并获取该网页的可下载PDF。 当POST /api/pdf/url-to-pdf请求到达时,控制器使用_pdfService后台将给定的URL转换为PDF字节,然后以文件下载的形式返回。 如果在转换过程中出现问题,它会优雅地响应一个清晰的错误信息。
让我们尝试使用网址"https://www.apple.com/nz"并测试POST请求。下面是我们获得的输出。
输出

添加自定义水印
public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
// Load PDF directly from file
var pdf = PdfDocument.FromFile(filePath);
pdf.ApplyWatermark(
$"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
75,
IronPdf.Editing.VerticalAlignment.Middle,
IronPdf.Editing.HorizontalAlignment.Center
);
return pdf.BinaryData;
}public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
// Load PDF directly from file
var pdf = PdfDocument.FromFile(filePath);
pdf.ApplyWatermark(
$"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
75,
IronPdf.Editing.VerticalAlignment.Middle,
IronPdf.Editing.HorizontalAlignment.Center
);
return pdf.BinaryData;
}IRON VB CONVERTER ERROR developers@ironsoftware.com在这里,我们只是手动加载一个本地的文件以进行测试。 然而,您可以调整这个,以便您的PDF API生成PDF文档,然后轻松地应用自定义水印。
水印输出

如何使用模板添加动态数据
对于真实世界的应用程序,您通常需要从模板生成带有动态数据的PDFs:
[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
// Simple template replacement
var html = request.Template;
foreach (var item in request.Data)
{
html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
}
var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
public string Template { get; set; }
public Dictionary<string, string> Data { get; set; }
public string FileName { get; set; } = "document.pdf";
}[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
// Simple template replacement
var html = request.Template;
foreach (var item in request.Data)
{
html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
}
var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
public string Template { get; set; }
public Dictionary<string, string> Data { get; set; }
public string FileName { get; set; } = "document.pdf";
}IRON VB CONVERTER ERROR developers@ironsoftware.com对于更高级的模板场景,请查看IronPDF的HTML到PDF文档。 您还可以探索CSHTML到PDF转换用于MVC应用程序和Razor到PDF用于Blazor应用程序。
如何优化性能?
在构建生产PDF API时,性能至关重要。 以下是关键的优化策略:
异步操作
当构建涉及使用I/O操作的项目时,明智的做法是使用异步编码。 如果您的PDF内容来自外部资源,这尤其有用,例如:
- 下载HTML页面(RenderUrlAsPdf)
- 通过HTTP获取图像、CSS或字体
- 读取/写入磁盘或云存储的文件
这些操作可以阻塞线程,但使用异步可以防止您的API线程空闲等待。
例:
public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
return await Task.Run(() =>
{
var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
return pdf.BinaryData;
});
}public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
return await Task.Run(() =>
{
var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
return pdf.BinaryData;
});
}IRON VB CONVERTER ERROR developers@ironsoftware.com渲染选项
配置IronPDF以获得最佳性能:
_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeoutIRON VB CONVERTER ERROR developers@ironsoftware.com如何保护您的PDF API?
对于任何生产API,安全性都是至关重要的。 这里是一个简单的API密钥身份验证方法:
// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string ApiKeyHeader = "X-API-Key";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("API Key required");
return;
}
// Validate API key (in production, check against database)
var validApiKey = context.RequestServices
.GetRequiredService<IConfiguration>()["ApiKey"];
if (apiKey != validApiKey)
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Invalid API Key");
return;
}
await _next(context);
}
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string ApiKeyHeader = "X-API-Key";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("API Key required");
return;
}
// Validate API key (in production, check against database)
var validApiKey = context.RequestServices
.GetRequiredService<IConfiguration>()["ApiKey"];
if (apiKey != validApiKey)
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Invalid API Key");
return;
}
await _next(context);
}
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();IRON VB CONVERTER ERROR developers@ironsoftware.com对于更高级的身份验证场景,请考虑:
- JWT身份验证 - API身份验证的行业标准
- OAuth 2.0 - 用于第三方集成
- Azure AD集成 - 企业身份验证
- API速率限制 - 防止滥用并确保公平使用
实际案例:发票生成API
让我们构建一个实际的发票生成端点,演示完整的实现。 此示例展示了如何使用生产.NET PDF API生成具有动态数据的专业发票。
首先,我们将在我们的Models文件夹中创建一个新文件。 在这里,我将其称之为Invoice.cs。 然后,将以下代码添加到您的新文件中。
public class Invoice
{
public string InvoiceNumber { get; set; }
public DateTime Date { get; set; }
public string CustomerName { get; set; }
public string CustomerAddress { get; set; }
public List<InvoiceItem> Items { get; set; }
public decimal Tax { get; set; }
}
public class InvoiceItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal Total => Quantity * UnitPrice;
}public class Invoice
{
public string InvoiceNumber { get; set; }
public DateTime Date { get; set; }
public string CustomerName { get; set; }
public string CustomerAddress { get; set; }
public List<InvoiceItem> Items { get; set; }
public decimal Tax { get; set; }
}
public class InvoiceItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal Total => Quantity * UnitPrice;
}IRON VB CONVERTER ERROR developers@ironsoftware.com然后,我们将需要为我们的发票生成器创建一个新的服务文件。 在您的Services文件夹中,添加以下代码。 对于我的,我创建了一个名为InvoiceService.cs的新文件。 这段代码将处理我们的发票PDF文件的样式和布局。
public class InvoiceService
{
private readonly ChromePdfRenderer _renderer;
public InvoiceService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.MarginTop = 10;
_renderer.RenderingOptions.MarginBottom = 10;
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
}
public byte[] GenerateInvoice(Invoice invoice)
{
var html = BuildInvoiceHtml(invoice);
// Add footer with page numbers
_renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
MaxHeight = 15,
HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
DrawDividerLine = true
};
var pdf = _renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
}
private string BuildInvoiceHtml(Invoice invoice)
{
var subtotal = invoice.Items.Sum(i => i.Total);
var taxAmount = subtotal * (invoice.Tax / 100);
var total = subtotal + taxAmount;
var itemsHtml = string.Join("", invoice.Items.Select(item =>
$@"<tr>
<td>{item.Description}</td>
<td class='text-center'>{item.Quantity}</td>
<td class='text-right'>${item.UnitPrice:F2}</td>
<td class='text-right'>${item.Total:F2}</td>
</tr>"));
return $@"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{
background-color: #f8f9fa;
padding: 20px;
margin-bottom: 20px;
}}
table {{
width: 100%;
border-collapse: collapse;
}}
th, td {{
padding: 10px;
border-bottom: 1px solid #ddd;
}}
th {{
background-color: #007bff;
color: white;
}}
.text-right {{ text-align: right; }}
.text-center {{ text-align: center; }}
.total-section {{
margin-top: 20px;
text-align: right;
}}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{invoice.InvoiceNumber}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd}</p>
</div>
<div>
<h3>Bill To:</h3>
<p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
</div>
<table>
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{itemsHtml}
</tbody>
</table>
<div class='total-section'>
<p>Subtotal: ${subtotal:F2}</p>
<p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
<h3>Total: ${total:F2}</h3>
</div>
</body>
</html>";
}
}public class InvoiceService
{
private readonly ChromePdfRenderer _renderer;
public InvoiceService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.MarginTop = 10;
_renderer.RenderingOptions.MarginBottom = 10;
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
}
public byte[] GenerateInvoice(Invoice invoice)
{
var html = BuildInvoiceHtml(invoice);
// Add footer with page numbers
_renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
MaxHeight = 15,
HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
DrawDividerLine = true
};
var pdf = _renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
}
private string BuildInvoiceHtml(Invoice invoice)
{
var subtotal = invoice.Items.Sum(i => i.Total);
var taxAmount = subtotal * (invoice.Tax / 100);
var total = subtotal + taxAmount;
var itemsHtml = string.Join("", invoice.Items.Select(item =>
$@"<tr>
<td>{item.Description}</td>
<td class='text-center'>{item.Quantity}</td>
<td class='text-right'>${item.UnitPrice:F2}</td>
<td class='text-right'>${item.Total:F2}</td>
</tr>"));
return $@"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{
background-color: #f8f9fa;
padding: 20px;
margin-bottom: 20px;
}}
table {{
width: 100%;
border-collapse: collapse;
}}
th, td {{
padding: 10px;
border-bottom: 1px solid #ddd;
}}
th {{
background-color: #007bff;
color: white;
}}
.text-right {{ text-align: right; }}
.text-center {{ text-align: center; }}
.total-section {{
margin-top: 20px;
text-align: right;
}}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{invoice.InvoiceNumber}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd}</p>
</div>
<div>
<h3>Bill To:</h3>
<p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
</div>
<table>
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{itemsHtml}
</tbody>
</table>
<div class='total-section'>
<p>Subtotal: ${subtotal:F2}</p>
<p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
<h3>Total: ${total:F2}</h3>
</div>
</body>
</html>";
}
}IRON VB CONVERTER ERROR developers@ironsoftware.com最后,您将需要创建一个新的控制器,以便通过API访问并创建一个新的发票。
[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
private readonly InvoiceService _invoiceService;
public InvoiceController(InvoiceService invoiceService)
{
_invoiceService = invoiceService;
}
[HttpPost("generate")]
public IActionResult GenerateInvoice([FromBody] Invoice invoice)
{
try
{
var pdfBytes = _invoiceService.GenerateInvoice(invoice);
var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
return File(pdfBytes, "application/pdf", fileName);
}
catch (Exception ex)
{
return StatusCode(500, $"Error generating invoice: {ex.Message}");
}
}
}[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
private readonly InvoiceService _invoiceService;
public InvoiceController(InvoiceService invoiceService)
{
_invoiceService = invoiceService;
}
[HttpPost("generate")]
public IActionResult GenerateInvoice([FromBody] Invoice invoice)
{
try
{
var pdfBytes = _invoiceService.GenerateInvoice(invoice);
var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
return File(pdfBytes, "application/pdf", fileName);
}
catch (Exception ex)
{
return StatusCode(500, $"Error generating invoice: {ex.Message}");
}
}
}IRON VB CONVERTER ERROR developers@ironsoftware.com发票输出

容器部署注意事项
虽然本教程侧重于本地开发,但这里是关于将您的PDF API容器化的简要概述:
基础Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
libgdiplus \
libc6-dev \
libx11-dev \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["dotnet", "PdfApiService.dll"]FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
libgdiplus \
libc6-dev \
libx11-dev \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["dotnet", "PdfApiService.dll"]IRON VB CONVERTER ERROR developers@ironsoftware.com有关您的.NET PDF API的详细部署指南,请参阅:
- IronPDF Docker文档 - 完整的容器化指南
- IronPDF Azure部署 - Azure Functions和App Service
- IronPDF AWS部署 - Lambda和EC2部署
- IronPDF Linux设置 - Linux特定配置
错误处理最佳实践
为了设计更具容错性的程序,最佳实践是实施全局错误处理程序,以获得一致的错误响应,例如下面所示:
// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
var response = new
{
error = "An error occurred processing your request",
message = ex.Message
};
await context.Response.WriteAsync(JsonSerializer.Serialize(response));
}
}// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
var response = new
{
error = "An error occurred processing your request",
message = ex.Message
};
await context.Response.WriteAsync(JsonSerializer.Serialize(response));
}
}IRON VB CONVERTER ERROR developers@ironsoftware.com对于特定的IronPDF故障排除场景,请参阅IronPDF故障排除指南。
结论
您现在已经构建了一个强大的.NET PDF API,使用ASP.NET Core和IronPDF可以处理多种文档生成场景。 这个REST API为您的应用程序提供集中化PDF操作的坚实基础。
关键要点:
- IronPDF使得Web API项目中的PDF生成变得简单,具有其基于Chrome的渲染
- 您可以轻松调整Web API以编辑现有PDF文档,利用IronPDF的高级编辑工具
- RESTful设计原则确保您的PDF API直观且易于维护
- 适当的错误处理和安全措施对于生产至关重要
- 通过异步操作和缓存进行性能优化可提高可扩展性
- 您将拥有支持桌面和Web应用程序的可扩展文档解决方案
IronPDF允许开发人员高效地创建PDF文档、保存PDF文件和转换HTML,使其成为现代.NET Framework应用程序中的必备PDF文档API。
下一步
准备好在您的生产.NET PDF API中实施IronPDF了吗? 以下是您的下一步操作:
今天就构建您的.NET PDF API,并通过IronPDF在整个应用程序生态系统中简化文档生成!
常见问题解答
什么是.NET PDF API?
一个.NET PDF API是一个库,允许开发人员在.NET应用程序中创建、编辑和提取PDF内容。它简化了复杂的PDF任务并确保PDF文件的有效管理。
一个.NET PDF API如何能够使我的应用程序受益?
一个.NET PDF API可以通过提供一致性、可维护性和可扩展性来增强您的应用程序中PDF文件的管理,如生成发票、报告、证书或合同。
一个.NET PDF API 有哪些常见用例?
一个.NET PDF API 的常见用例包括在桌面和网络应用程序中生成发票、创建报告、制作证书和管理合同。
IronPDF如何简化PDF生成任务?
IronPDF通过提供强大的库简化了PDF生成任务,使得文档内容、PDF页面和表单字段的管理变得简单,更容易维护和扩展应用程序。
IronPDF能够处理PDF表单字段吗?
是的,IronPDF可以高效管理PDF表单字段,允许开发者在PDF文件中创建、填写和提取表单数据。
IronPDF适用于桌面和网络应用程序吗?
当然,IronPDF专为跨桌面和网络应用程序无缝工作而设计,提供一致且可扩展的PDF管理解决方案。
是什么让IronPDF成为.NET开发人员可靠的选择?
IronPDF是.NET开发人员可靠的选择,因为其使用简单、功能全面,并能够简化PDF任务,从而提高生产力和应用程序性能。
IronPDF支持PDF提取功能吗?
是的,IronPDF支持PDF提取功能,允许您有效地从PDF文件中提取文本、图像和其他数据。
IronPDF如何在管理PDF方面提高可扩展性?
IronPDF通过提供一个集中化的PDF生成服务来提高可扩展性,它可以在不牺牲性能的情况下处理日益增长的需求,非常适合增长中的应用程序。
IronPDF为.NET应用程序提供了什么样的支持?
IronPDF为.NET应用程序提供了广泛的支持,包括详细的文档、示例代码和响应迅速的支持团队,协助开发者集成PDF功能。
IronPDF 是否完全兼容 .NET 10?
是的——IronPDF 与 .NET 10 完全兼容。它支持 .NET 10 引入的所有性能、语言和运行时增强功能,并且可以像在 .NET 6、7、8 和 9 等以前的版本中一样,在 .NET 10 项目中开箱即用。






