跳至頁尾內容
使用 IRONPDF

如何在 C# 中將 Fluent Validation 與 IronPDF 結合使用

什麼是 Fluent 驗證?

FluentValidation是一個 .NET 驗證函式庫,它有助於建立強型別驗證規則。 它採用流暢的介面和 lambda 表達式,使程式碼更易讀、更易於維護。 您可以不使用模型類別中的資料註解或手動驗證,而是使用 Fluent Validation 為驗證邏輯建立一個單獨的類別。

Fluent Validation 為驗證過程帶來了更大的靈活性。 Fluent Validation 內建了常見場景的驗證器,能夠建立自訂驗證,並且可以輕鬆地將驗證規則串聯起來,是 .NET Core 工具包中一個強大的工具。

了解 Fluent 驗證

Fluent Validation 是一個適用於 .NET 的開源程式庫,它可以輕鬆地為模型類別建立驗證規則。

1.驗證器:驗證器是封裝驗證邏輯的類別。 它們通常是透過繼承自AbstractValidator<T>而創建的。 AbstractValidator<T>基類。 2.規則:規則是屬性必須滿足的驗證條件。 規則是在驗證器類別中使用RuleFor方法定義的。 3.驗證失敗:如果規則失敗,Fluent Validation 會建立一個ValidationFailure對象,其中包含有關錯誤的詳細信息,包括屬性名稱和錯誤訊息。

什麼是 IronPDF?

IronPDF - Convert HTML to PDF in C#是一個功能強大的 .NET 程式庫,可讓您從 HTML 內容產生 PDF 文件。 無論您需要建立發票、報告或任何其他類型的文檔,IronPDF 都能提供易於使用的解決方案。 它與您的 ASP.NET Core 應用程式無縫集成,使您只需幾行程式碼即可產生高品質的 PDF 檔案。

將 Fluent Validation 與 IronPDF 結合使用

現在我們已經了解了 Fluent Validation 和 IronPDF 是什麼,讓我們看看它們如何一起使用。 本教學將協助建立發票產生器,其中發票內容將使用 ASP.NET Core 中的 FluentValidation 進行驗證,然後再使用 IronPDF 產生 PDF。

設定專案

首先,讓我們在 Visual Studio 或您喜歡的開發環境中建立一個新的控制台應用程式。

  1. 開啟 Visual Studio,然後前往檔案 > 新建 > 專案
  2. 選擇"控制台應用程式(ASP.NET Core)"作為專案模板,並為您的專案提供一個名稱。

    如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 1:建立一個新的控制台應用程式 建立一個新的控制台應用程式

  3. 點選"下一步"按鈕,透過命名項目和選擇儲存庫位置來設定項目。

    如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 2:配置新應用程式 配置新應用程式

  4. 按一下"下一步"按鈕,然後選擇 .NET Framework。 建議使用最新的 .NET Framework (7)。

    如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 3:.NET Framework 選擇 .NET Framework 選擇

  5. 點選"建立"按鈕建立項目。

安裝所需軟體包

專案建立完成後,加入 Fluent Validation 和 IronPDF 所需的 NuGet 套件。

  1. 在解決方案資源管理器中以滑鼠右鍵按一下項目,然後選擇"管理 NuGet 套件"。
  2. 搜尋"FluentValidation",然後點擊"安裝"將該軟體包新增至您的專案。

    如何在 C# 中將 Fluent Validation 與 IronPDF 結合使用,圖 4:在 NuGet 套件管理器 UI 中安裝 FluentValidation 套件 在 NuGet 套件管理器 UI 中安裝 FluentValidation 套件

  3. 同樣地,搜尋" IronPDF - 強大的 .NET PDF 庫",並安裝 IronPDF 軟體包。

或者,您可以使用NuGet 套件管理器控制台,透過以下命令安裝 IronPDF:

Install-Package IronPdf

如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 5:在套件管理器控制台中安裝 IronPDF 套件 在軟體包管理器控制台中安裝 IronPdf 軟體包

專案設定完畢,所需軟體包也已安裝,接下來我們來定義 PDF 內容類。

定義 PDF 內容

在這個範例中,我們將使用兩個類別InvoiceContentInvoiceItem )中的 HTML 程式碼來建立一個簡單的發票 PDF。

using System.Collections.Generic;
using System.Linq;

public abstract class PdfContent
{
    // Abstract method to generate the HTML string
    public abstract string RenderHtml();
}

public class InvoiceContent : PdfContent
{
    public string CustomerName { get; set; }
    public string Address { get; set; }
    public List<InvoiceItem> InvoiceItems { get; set; }

    // Constructs the HTML representation of the invoice
    public override string RenderHtml()
    {
        string invoiceItemsHtml = string.Join("", InvoiceItems.Select(item => $"<li>{item.Description}: {item.Price}</li>"));
        return $"<h1>Invoice for {CustomerName}</h1><p>{Address}</p><ul>{invoiceItemsHtml}</ul>";
    }
}

public class InvoiceItem
{
    public string Description { get; set; }
    public decimal Price { get; set; }
}
using System.Collections.Generic;
using System.Linq;

public abstract class PdfContent
{
    // Abstract method to generate the HTML string
    public abstract string RenderHtml();
}

public class InvoiceContent : PdfContent
{
    public string CustomerName { get; set; }
    public string Address { get; set; }
    public List<InvoiceItem> InvoiceItems { get; set; }

    // Constructs the HTML representation of the invoice
    public override string RenderHtml()
    {
        string invoiceItemsHtml = string.Join("", InvoiceItems.Select(item => $"<li>{item.Description}: {item.Price}</li>"));
        return $"<h1>Invoice for {CustomerName}</h1><p>{Address}</p><ul>{invoiceItemsHtml}</ul>";
    }
}

public class InvoiceItem
{
    public string Description { get; set; }
    public decimal Price { get; set; }
}
$vbLabelText   $csharpLabel

在上面的程式碼中,定義了一個抽象的PdfContent類,其中包含一個名為RenderHtml的抽象方法。 InvoiceContent類別繼承自PdfContent ,表示發票 PDF 的內容。 它包含客戶姓名、地址和發票項目清單等屬性。 InvoiceItem類別包含兩個屬性:"描述"和"價格"。 RenderHtml方法根據內容產生發票的 HTML 標記。

現在 PDF 內容已經定義好了,讓我們繼續使用 Fluent Validation 建立驗證規則。

建立驗證規則

若要為InvoiceContent類別建置驗證規則,請建立一個名為InvoiceContentValidator的驗證器類別。 此類別將繼承自AbstractValidator<InvoiceContent>這是由 FluentValidation 提供的。

using FluentValidation;

public class InvoiceContentValidator : AbstractValidator<InvoiceContent>
{
    public InvoiceContentValidator()
    {
        RuleFor(content => content.CustomerName).NotEmpty().WithMessage("Customer name is required.");
        RuleFor(content => content.Address).NotEmpty().WithMessage("Address is required.");
        RuleFor(content => content.InvoiceItems).NotEmpty().WithMessage("At least one invoice item is required.");
        RuleForEach(content => content.InvoiceItems).SetValidator(new InvoiceItemValidator());
    }
}

public class InvoiceItemValidator : AbstractValidator<InvoiceItem>
{
    public InvoiceItemValidator()
    {
        RuleFor(item => item.Description).NotEmpty().WithMessage("Description is required.");
        RuleFor(item => item.Price).GreaterThanOrEqualTo(0).WithMessage("Price must be greater than or equal to 0.");
    }
}
using FluentValidation;

public class InvoiceContentValidator : AbstractValidator<InvoiceContent>
{
    public InvoiceContentValidator()
    {
        RuleFor(content => content.CustomerName).NotEmpty().WithMessage("Customer name is required.");
        RuleFor(content => content.Address).NotEmpty().WithMessage("Address is required.");
        RuleFor(content => content.InvoiceItems).NotEmpty().WithMessage("At least one invoice item is required.");
        RuleForEach(content => content.InvoiceItems).SetValidator(new InvoiceItemValidator());
    }
}

public class InvoiceItemValidator : AbstractValidator<InvoiceItem>
{
    public InvoiceItemValidator()
    {
        RuleFor(item => item.Description).NotEmpty().WithMessage("Description is required.");
        RuleFor(item => item.Price).GreaterThanOrEqualTo(0).WithMessage("Price must be greater than or equal to 0.");
    }
}
$vbLabelText   $csharpLabel

在原始碼中,定義了InvoiceContentValidator類,該類別繼承自AbstractValidator<InvoiceContent> 。 在驗證器類別的建構子中, RuleFor方法為InvoiceContent類別的每個屬性定義驗證規則。

例如, RuleFor(content =&gt; content.CustomerName)指定客戶名稱不能為空。 同樣,也為地址和發票項目屬性定義了驗證規則。

RuleForEach方法遍歷InvoiceItems清單中的每個項目,並套用InvoiceItemValidatorInvoiceItemValidator類別包含InvoiceItem類別的驗證規則。

有了這些驗證規則,我們接下來使用 IronPDF 產生 PDF。

使用 IronPDF 產生 PDF

IronPDF - 產生和編輯 PDF 文件是一個流行的 .NET 庫,用於建立和操作 PDF 文件。 我們將使用 IronPDF 根據已驗證的發票內容產生 PDF 文件。

using IronPdf;
using FluentValidation;

public class PdfService
{
    // Generates a PDF document for the provided content
    public PdfDocument GeneratePdf<T>(T content) where T : PdfContent
    {
        // Validate the content using the appropriate validator
        var validator = GetValidatorForContent(content);
        var validationResult = validator.Validate(content);

        // Check if validation is successful
        if (!validationResult.IsValid)
        {
            throw new FluentValidation.ValidationException(validationResult.Errors);
        }

        // Generate the PDF using IronPDF
        var renderer = new ChromePdfRenderer();
        return renderer.RenderHtmlAsPdf(content.RenderHtml());
    }

    // Retrieves the appropriate validator for the content
    private IValidator<T> GetValidatorForContent<T>(T content) where T : PdfContent
    {
        if (content is InvoiceContent)
        {
            return (IValidator<T>)new InvoiceContentValidator();
        }
        else
        {
            throw new NotSupportedException("Unsupported content type.");
        }
    }
}
using IronPdf;
using FluentValidation;

public class PdfService
{
    // Generates a PDF document for the provided content
    public PdfDocument GeneratePdf<T>(T content) where T : PdfContent
    {
        // Validate the content using the appropriate validator
        var validator = GetValidatorForContent(content);
        var validationResult = validator.Validate(content);

        // Check if validation is successful
        if (!validationResult.IsValid)
        {
            throw new FluentValidation.ValidationException(validationResult.Errors);
        }

        // Generate the PDF using IronPDF
        var renderer = new ChromePdfRenderer();
        return renderer.RenderHtmlAsPdf(content.RenderHtml());
    }

    // Retrieves the appropriate validator for the content
    private IValidator<T> GetValidatorForContent<T>(T content) where T : PdfContent
    {
        if (content is InvoiceContent)
        {
            return (IValidator<T>)new InvoiceContentValidator();
        }
        else
        {
            throw new NotSupportedException("Unsupported content type.");
        }
    }
}
$vbLabelText   $csharpLabel

PdfService類別提供了一個GeneratePdf方法。 此方法接受一個PdfContent物件作為輸入,並根據驗證後的內容產生 PDF 文件。

首先,它透過呼叫GetValidatorForContent方法來檢索內容的適當驗證器,該方法檢查內容的類型並傳回對應的驗證器。 在我們的案例中,我們支援InvoiceContent並使用InvoiceContentValidator

接下來,透過呼叫驗證器的Validate方法,使用驗證器對內容進行驗證。 驗證結果儲存在ValidationResult物件中。

如果驗證失敗( !validationResult.IsValid ),則會拋出FluentValidation.ValidationException異常,其中包含驗證錯誤。 否則,PDF 將使用 IronPDF 產生。

建立ChromePdfRenderer實例,將 HTML 內容渲染為 PDF。 RenderHtmlAsPdf方法在renderer物件上被調用,傳入content.RenderHtml方法產生的 HTML,從而產生 PDF 文件。

現在我們已經定義了 PDF 生成邏輯,接下來讓我們處理可能出現的任何驗證錯誤。

處理驗證錯誤

當發生驗證錯誤時,我們希望顯示錯誤訊息並妥善處理它。 讓我們修改Program類別的Main方法,使其能夠處理任何異常並向使用者顯示有意義的訊息。

using System;
using System.Collections.Generic;

public class Program
{
    static void Main(string[] args)
    {
        var pdfService = new PdfService();

        // Test 1: Empty Customer Name
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem> {
                    new InvoiceItem { Description = "Item 1", Price = 19.99M },
                    new InvoiceItem { Description = "Item 2", Price = 29.99M }
                }
            };

            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }

        // Test 2: Empty InvoiceItems
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "John Doe",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem>()  // Empty list
            };

            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }

        // Successful generation
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "John Doe",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem> {
                    new InvoiceItem { Description = "Item 1", Price = 19.99M },
                    new InvoiceItem { Description = "Item 2", Price = 29.99M }
                }
            };
            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }
    }
}
using System;
using System.Collections.Generic;

public class Program
{
    static void Main(string[] args)
    {
        var pdfService = new PdfService();

        // Test 1: Empty Customer Name
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem> {
                    new InvoiceItem { Description = "Item 1", Price = 19.99M },
                    new InvoiceItem { Description = "Item 2", Price = 29.99M }
                }
            };

            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }

        // Test 2: Empty InvoiceItems
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "John Doe",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem>()  // Empty list
            };

            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }

        // Successful generation
        try
        {
            var invoiceContent = new InvoiceContent
            {
                CustomerName = "John Doe",
                Address = "123 Main St, Anytown, USA",
                InvoiceItems = new List<InvoiceItem> {
                    new InvoiceItem { Description = "Item 1", Price = 19.99M },
                    new InvoiceItem { Description = "Item 2", Price = 29.99M }
                }
            };
            var pdfDocument = pdfService.GeneratePdf(invoiceContent);
            pdfDocument.SaveAs("C:\\TestInvoice.pdf");
            Console.WriteLine("PDF generated successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating PDF: " + ex.Message);
        }
    }
}
$vbLabelText   $csharpLabel

上面的程式碼中使用了try-catch區塊來捕獲可能發生的任何異常。 如果捕獲到異常,將使用Console.WriteLine向使用者顯示錯誤訊息。

現在讓我們用不同的場景來測試這個應用程序,以驗證 PDF 產生和驗證規則。

測試應用程式

在程式碼範例中,有三種場景需要測試:

  1. 客戶名稱為空:將客戶名稱留空會觸發驗證錯誤。
  2. 空發票項目:提供一個空的發票項目清單以觸發驗證錯誤。
  3. 生成成功:提供有效內容以成功產生 PDF。

運行應用程式並觀察控制台中的輸出。

Error generating PDF: Validation failed:
    -- CustomerName: Customer name is required. Severity: Error
Error generating PDF: Validation failed:
    -- InvoiceItems: At least one invoice item is required. Severity: Error
PDF generated successfully!

如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 6:控制台中的輸出錯誤 控制台輸出錯誤

如何在 C# 中使用 Fluent Validation 和 IronPDF,圖 7:輸出的 PDF 文件 輸出的PDF文件

如預期的那樣,前兩種情況會顯示驗證錯誤,而第三種情況會顯示成功訊息。

結論

本教學探討了 Fluent Validation 以及如何將其與 IronPDF 結合使用來產生 PDF 文件。 首先設定控制台應用程式並定義 PDF 內容類別。 然後,使用 Fluent Validation 建立驗證規則,並在不同場景下測試 PDF 產生。

Fluent Validation 為 .NET 應用程式中的物件驗證提供了一種靈活且易於使用的方法。 它允許您以強類型方式定義驗證規則,自訂錯誤訊息,並優雅地處理驗證錯誤。

IronPDF 免費試用和許可資訊提供免費試用,許可起價為每位開發者 499 美元。

常見問題解答

如何在 C# 中將 Fluent Validation 與 PDF 生成整合?

要將 Fluent Validation 與 C# 中的 PDF 生成集成,您可以在 Visual Studio 中設定控制台應用程序,透過 NuGet 安裝 FluentValidation 和 IronPDF 包,並使用 Fluent Validation 定義模型驗證邏輯,同時使用 IronPDF 生成 PDF。

設定用於產生和驗證 PDF 的專案需要哪些步驟?

若要設定項目,請在 Visual Studio 中建立新的控制台應用程序,透過 NuGet 安裝 IronPDF 和 FluentValidation 套件,然後使用對應的庫定義 PDF 內容和驗證規則。

如何使用 .NET 函式庫從 HTML 內容產生 PDF?

您可以使用 IronPDF 的RenderHtmlAsPdf方法從 HTML 內容產生 PDF,該方法可讓您將 HTML 字串或檔案轉換為高品質的 PDF。

教程中 PdfService 類別的用途是什麼?

本教程中的 PdfService 類別旨在管理 PDF 生成,它首先使用 Fluent Validation 驗證內容。驗證成功後,它會使用 IronPDF 的ChromePdfRendererRenderHtmlAsPdf方法建立 PDF。

如何使用 Fluent Validation 定義驗證規則?

Fluent Validation 中的驗證規則是透過建立一個繼承自AbstractValidator驗證器類別來定義的。 AbstractValidator在該類別中, RuleFor方法用於指定每個屬性的條件,從而允許自訂錯誤訊息和規則鏈。

如果在產生 PDF 檔案過程中驗證失敗會發生什麼情況?

如果驗證失敗,Fluent Validation 會拋出一個ValidationException ,其中包含有關驗證錯誤的詳細信息,可用於告知使用者哪裡出了問題。

我可以使用 Fluent Validation 進行複雜物件驗證嗎?

是的,Fluent Validation 支援透過使用子驗證器進行複雜物件驗證,讓您可以驗證模型中的巢狀屬性和集合。

如何在 Fluent Validation 中自訂錯誤訊息?

在 Fluent Validation 中,可以使用WithMessage方法為RuleFor指定的每個驗證規則定義自訂錯誤訊息。

PDF生成庫是否有試用版?

是的,IronPDF 為開發者提供免費試用版,用於測試庫的功能,並提供許可選項,起價為每位開發者 499 美元。

IronPDF 是否完全相容於 .NET 10?

是的。 IronPDF 完全相容於 .NET 10,並支援包括 Windows、Linux 和 macOS 在內的多種平台,以及各種專案類型(控制台、Web、桌面、Blazor 等)。它無需任何額外設定即可在最新的運行時環境中直接運作。

柯蒂斯·週
技術撰稿人

Curtis Chau擁有卡爾頓大學電腦科學學士學位,專長於前端開發,精通Node.js、TypeScript、JavaScript和React。他熱衷於打造直覺美觀的使用者介面,喜歡使用現代框架,並擅長撰寫結構清晰、視覺效果出色的使用者手冊。

除了開發工作之外,柯蒂斯對物聯網 (IoT) 也抱有濃厚的興趣,致力於探索硬體和軟體整合的創新方法。閒暇時,他喜歡玩遊戲和製作 Discord 機器人,將他對科技的熱愛與創造力結合。