IRONSOFTWAREHOME
使用IRONPDF

如何使用IronPDF在C#中合併兩個PDF字節陣列

Curtis Chau
Curtis Chau
Updated: 2026年3月9日

在ASP.NET中使用C#從資料庫中檢索PDF文件需要三個步驟:查詢資料庫表的二進位BLOB欄位,使用IronPDF將位元組載入到File()響應將位元組返回到瀏覽器。 IronPDF處理渲染、水印和安全功能,因此您可以專注於資料存取邏輯。

如何安裝IronPDF for ASP.NET?

在撰寫任何PDF檢索程式碼之前,通過NuGet套件管理器將IronPDF新增到您的項目中:

PM > Install-Package IronPdf

安裝後,請在呼叫任何IronPDF方法之前於appsettings.json中設置您的授權金鑰:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

IronPDF支持.NET 10、.NET 8、.NET 6和.NET Framework 4.6.2+。 它可以在Windows、Linux和macOS上運行,無需任何額外的依賴項或無頭瀏覽器安裝。 提供免費試用授權以供評估。

如何設置SQL Server資料庫表?

最常見的方法是將PDF文件作為二進位資料儲存在SQL Server的VARBINARY(MAX)欄位中。 這會將文件及其元資料一同保存在一個表中,簡化備份並避免檔案系統路徑管理。

使用以下SQL腳本建立儲存表:

// SQL Server table definition (run this in SSMS or via EF migrations)
// CREATE TABLE PdfDocuments (
//     Id INT IDENTITY(1,1) PRIMARY KEY,
//     FileName NVARCHAR(255) NOT NULL,
//     FileContent VARBINARY(MAX) NOT NULL,
//     UploadedAt DATETIME2 DEFAULT GETUTCDATE()
// );

一旦表存在,請於appsettings.json中配置連接字串:

// appsettings.json snippet (not C# -- shown as reference)
// "ConnectionStrings": {
//   "DefaultConnection": "Server=localhost;Database=PdfStorage;Integrated Security=True;"
// }

通過依賴項注入於Program.cs中註冊連接字串:

using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton<IConfiguration>(builder.Configuration);

IronPdf.License.LicenseKey = builder.Configuration["IronPdf:LicenseKey"];

var app = builder.Build();
app.MapControllers();
app.Run();

如何從ASP.NET Core中的SQL Server檢索PDF?

檢索模式遵循三個步驟:打開連接,執行參數化的SELECT查詢,並將二進位欄讀入byte[]。 然後IronPDF將該陣列載入到PdfDocument物件中以進行可選處理,在流式傳輸到客戶端之前。

構建API控制器

建立一個控制器來公開用於內聯顯示和檔案下載的GET端點:

using IronPdf;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;

[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly string _connectionString;

    public PdfController(IConfiguration configuration)
    {
        _connectionString = configuration.GetConnectionString("DefaultConnection")
            ?? throw new InvalidOperationException("Connection string not found.");
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetPdf(int id)
    {
        byte[] pdfBytes = await RetrievePdfBytesAsync(id);
        if (pdfBytes is null || pdfBytes.Length == 0)
            return NotFound("PDF document not found.");

        // Load into IronPDF for validation or optional modification
        using var pdfDocument = new PdfDocument(pdfBytes);

        // Inline display -- browser opens PDF viewer
        Response.Headers.Append("Content-Disposition", "inline; filename=\"document.pdf\"");
        return File(pdfDocument.BinaryData, "application/pdf");
    }

    private async Task<byte[]> RetrievePdfBytesAsync(int documentId)
    {
        await using var connection = new SqlConnection(_connectionString);
        await connection.OpenAsync();

        const string query = "SELECT FileContent FROM PdfDocuments WHERE Id = @Id";
        await using var command = new SqlCommand(query, connection);
        command.Parameters.AddWithValue("@Id", documentId);

        var result = await command.ExecuteScalarAsync();
        return result as byte[] ?? Array.Empty<byte>();
    }
}

此控制器使用參數化查詢以防止SQL注入,以SqlCommandPdfDocument類驗證位元組陣列並公開BinaryData屬性以進行流式傳輸。

返回命名檔案以供下載

當使用者需要保存文件而非內聯查看時,將attachment並傳遞原始檔案名:

[HttpGet("download/{id}")]
public async Task<IActionResult> DownloadPdf(int id)
{
    await using var connection = new SqlConnection(_connectionString);
    await connection.OpenAsync();

    const string query = "SELECT FileName, FileContent FROM PdfDocuments WHERE Id = @Id";
    await using var command = new SqlCommand(query, connection);
    command.Parameters.AddWithValue("@Id", documentId);

    await using var reader = await command.ExecuteReaderAsync();
    if (!await reader.ReadAsync())
        return NotFound("Document not found.");

    var fileName = reader.GetString(reader.GetOrdinal("FileName"));
    var pdfBytes = (byte[])reader["FileContent"];

    using var pdfDocument = new PdfDocument(pdfBytes);
    return File(pdfDocument.BinaryData, "application/pdf", fileName);
}

attachment。 ASP.NET Core正確處理包含空格的檔案名的引用。

如何向檢索的PDF新增水印?

最實用的後檢索操作之一是在每頁上加蓋水印,然後提供文件。 這對於機密報告、草稿文件或任何需要可見安全標記的文件都很有用。

使用IronPDF應用HTML水印

IronPDF的水印API接受任何HTML字串,這意味著您可以使用內聯CSS樣式化水印文字。 將不透明度設置得足夠低,使底層內容仍可讀:

[HttpGet("watermarked/{id}")]
public async Task<IActionResult> GetWatermarkedPdf(int id)
{
    byte[] pdfBytes = await RetrievePdfBytesAsync(id);
    if (pdfBytes is null || pdfBytes.Length == 0)
        return NotFound("PDF document not found.");

    using var pdfDocument = new PdfDocument(pdfBytes);

    // HTML watermark applied to every page
    string watermarkHtml = "<h2 style='color:red; opacity:0.4; font-family:Arial;'>CONFIDENTIAL</h2>";
    pdfDocument.ApplyWatermark(
        watermarkHtml,
        rotation: 30,
        verticalAlignment: VerticalAlignment.Middle,
        horizontalAlignment: HorizontalAlignment.Center
    );

    return File(pdfDocument.BinaryData, "application/pdf");
}

ApplyWatermark方法接受標準HTML和CSS,因此您可以完全控制字型、顏色、不透明度和位置。 水印會自動應用於文件中的所有頁面。 如需其他PDF操作功能,包括加蓋圖像、新增頁眉和頁腳、或合併多個文件,請參閱IronPDF文件。

如何將上傳的PDF重新儲存到SQL Server中?

完成回路需要一個上傳端點,該端點讀取傳入的表單文件並將其寫入資料庫。 這與上面的檢索端點結合形成一個完整的文件管理系統:

[HttpPost("upload")]
public async Task<IActionResult> UploadPdf(IFormFile file)
{
    if (file is null || file.Length == 0)
        return BadRequest("No file uploaded.");

    if (!file.ContentType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase))
        return BadRequest("Only PDF files are accepted.");

    using var memoryStream = new MemoryStream();
    await file.CopyToAsync(memoryStream);
    byte[] pdfBytes = memoryStream.ToArray();

    // Validate using IronPDF before storage
    using var pdfDocument = new PdfDocument(pdfBytes);

    await using var connection = new SqlConnection(_connectionString);
    await connection.OpenAsync();

    const string insertQuery = @"
        INSERT INTO PdfDocuments (FileName, FileContent)
        VALUES (@FileName, @FileContent);
        SELECT SCOPE_IDENTITY();";

    await using var command = new SqlCommand(insertQuery, connection);
    command.Parameters.AddWithValue("@FileName", file.FileName);
    command.Parameters.AddWithValue("@FileContent", pdfDocument.BinaryData);

    var newId = Convert.ToInt32(await command.ExecuteScalarAsync());
    return Ok(new { id = newId, fileName = file.FileName });
}

使用PdfDocument在儲存前驗證,確保只有可解析、格式良好的PDF文件進入資料庫。 如果位元組陣列損壞或截斷,IronPDF會拋出一個例外,您可以捕獲並返回為400 Bad Request響應。

PDF儲存的關鍵表和欄型別是什麼?

您使用的模式會影響查詢性能和儲存效率。 下表顯示了建議的SQL Server欄配置:

推薦的SQL Server PDF BLOB儲存模式
資料型別目的
IdINT IDENTITY主鍵,自增
FileNameNVARCHAR(255)下載標頭的原始檔案名
FileContentVARBINARY(MAX)原始PDF二進位資料(BLOB)
ContentTypeNVARCHAR(100)MIME型別,例如 application/pdf
FileSizeBytesBIGINT儲存大小以進行配額管理
UploadedAtDATETIME2審核用的UTC時間戳
UploadedByNVARCHAR(100)存取控制的使用者身份

對於需要SQL Server文件串流的大規模系統,微軟記錄了FILESTREAM功能作為一種選擇,將大型BLOB儲存在文件系統上,同時仍可通過T-SQL查詢。 但是,對於大多數ASP.NET應用程式,提供的文件高達幾百MB,VARBINARY(MAX)行記憶體儲效果良好,並簡化了部署。

如何處理錯誤並優化性能?

在生產環境中進行可靠的PDF檢索要求在每一層上進行錯誤處理——資料庫、IronPDF和HTTP響應。 下表總結了關鍵做法:

PDF檢索的錯誤處理和性能模式
關注點建議理由
連接處置await using語句防止連接池耗盡
PdfDocument處置using語句迅速釋放非管理的記憶體
SQL注入只用參數化的查詢防止惡意輸入更改查詢
檔案型別驗證檢查MIME型別和魔術位元組在儲存之前阻止非PDF上傳
大文件處理使用FileStreamResult流式響應避免將整個文件載入到伺服器的記憶體中
快取Use IMemoryCache or IDistributedCache減少重複的資料庫回合
非同步操作async/await全程使用在磁碟和網路等待期間保持執行緒自由

對於連接字串管理,將值儲存在appsettings.json中,切勿在源文件中硬編碼。 在本地開發期間使用ASP.NET Core的內建秘密管理,在生產環境中使用Azure秘鑰保管庫或AWS秘密管理器。 絕不能將連接字串或授權金鑰提交到源控制中。

在提供大型PDF文件時,考慮返回一個由FileStreamResult,而不是將整個位元組陣列載入到記憶體中。 對於非常大的文件——超過100 MB——SQL Server FILESTREAM API允許直接從文件系統塊狀流化。

快取頻繁存取的文件

如果某些PDF文件被重複請求——例如,條款和條件文件或產品目錄——在IMemoryCache中快取位元組陣列可以避免重複的資料庫回合。 在IMemoryCache,然後注入到控制器中,在查詢資料庫之前檢查快取。 設置一個絕對過期,與文件的預期更新頻率相匹配。 當文件更新時,以密鑰移除快取條目,使下一次請求獲取新版。

對於分佈式場景——例如具有多個伺服器實例的負載均衡部署——用靠Redis或SQL Server支持的IMemoryCache。 ASP.NET Core的分佈式快取抽象保持控制器程式碼幾乎不變; 只有Program.cs中的註冊改變。

如何跨平台部署使用IronPDF的PDF檢索?

IronPDF可以在Linux、Windows和macOS上運行,無需單獨的Chromium安裝或任何配置更改。 同一NuGet包針對所有平台,因此無論您部署到:

  • 使用IIS的Windows伺服器
  • Docker或Kubernetes上的Ubuntu容器
  • Azure應用服務(Linux或Windows)
  • AWS Elastic Beanstalk

部署到Docker和Linux

對於Docker部署,將IronPDF依賴項新增到您的Dockerfile中。IronPDF Linux文件提供了Debian和Alpine基礎映像所需的精確apt包。 典型的多階段Dockerfile在運行時映像階段中安裝OS依賴項,然後在上面複製已發佈的ASP.NET應用。當使用Azure時,Azure部署指南涵蓋應用服務配置,包括支持PDF渲染的記憶體和CPU設置。

由於IronPDF捆綁其自己的基於Chromium的渲染引擎,您不需要在伺服器上安裝單獨的瀏覽器。 這相比需要系統級瀏覽器的解決方案大大簡化了Linux容器設置。 IronPDF團隊針對每次釋放測試了最常用的Linux基礎映像,因此您可以相信Alpine或Debian容器可以即開即用。

使用Entity Framework Core替代ADO.NET

IronPDF也能與Entity Framework Core整合,作為替代原始ADO.NET的方式。 如果您的項目已經使用EF Core,您可以將byte[]屬性,並讓EF處理查詢生成。 這種方法大大減少了樣板程式碼,並使通過EF的LINQ提供程式新增過濾、分頁和審核行為變得更容易。

權衡是EF Core將整個BLOB載入到為實體圖的一部分的記憶體中。 對於非常大的PDF文件,考慮使用原始ADO.NET或EF Core的FromSql方法、僅選擇位元組欄而不是完整實體的投影。

您的下一步該怎麼做?

在ASP.NET Core中使用C#和IronPDF從SQL Server資料庫檢索PDF文件遵循明確的模式:使用參數化SELECT查詢BLOB欄,將位元組載入到Content-Disposition標頭一同返回二進制資料。 IronPDF增加了在文件離開伺服器之前驗證、水印、合併或保護文件的能力。

要深入了解IronPDF的文件管理功能,請探索以下資源:

開始使用免費的IronPDF試用授權來不限功能地測試所有功能。 試用版產生帶水印的輸出; 通過應用付費授權金鑰移除水印。 完整的API參考文件和程式碼範例都在IronPDF網站上可用,以便您使用本文中使用的每個方法。

如果您的項目已經使用Entity Framework Core,IronPDF EF Core整合指南顯示了如何在保持相同IronPDF處理流水線的情況下,用實體模型替換原始ADO.NET。對於使用.NET 10和最新ASP.NET Core功能的團隊,這裡描述的模式可以不進行修改地運行——IronPDF支持所有有效的.NET LTS和STS釋放。

查看IronPDF定價頁面以尋找適合您部署的授權等級。 單一開發人員授權涵蓋本地開發和測試; 重新分發授權可供SaaS產品和具有多台伺服器的內部部署。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

...
閱讀更多

相關文章

Key in blue circle

立即免費取得 30 天試用金鑰

無任何限制。100% 解鎖。無需信用卡。

bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
預訂您的免費現場演示
Booking Badge

受到全球數百萬工程師的信任

Iron Software的客戶標誌
獲取您的無義務諮詢
填寫以下表格或電子郵件sales@ironsoftware.com
您的詳細資訊將始終保密
受到全球數百萬工程師的信任
Iron Software的客戶標誌
立即獲取您的30天試用金鑰
無需信用卡或帳戶建立