使用 IRONPDF

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

已更新 2024年3月17日
分享:

什麼是 Fluent Validation?

FluentValidation 是一個 .NET 驗證庫,有助於建立強類型的驗證規則。這是通過提供流暢的接口和 lambda 表達式來完成的,使代碼更加可讀和易於維護。與其在您的模型類中使用數據註釋或手動驗證,您可以使用 Fluent Validation 來構建一個單獨的類來實現驗證邏輯。

Fluent Validation 為驗證帶來了更多的靈活性。它內建常見場景的驗證器、能夠構建自定義驗證,並且簡單地將驗證規則串聯在一起,Fluent Validation 是 .NET Core 工具包中的一個強大工具。

理解 Fluent Validation

Fluent Validation 是一個用於 .NET 的開源庫,使為模型類建立驗證規則變得簡單。

  1. 驗證器: 驗證器是封裝驗證邏輯的類。它們通常透過繼承 AbstractValidator 來創建。`基類。

  2. 規則: 規則是一個屬性必須滿足的驗證條件。規則是使用驗證器類中的 RuleFor 方法定義的。

  3. 驗證失敗: 如果規則失敗,Fluent Validation 會創建一個 ValidationFailure 對象,其中包含關於錯誤的詳細資訊,包括屬性名稱和錯誤訊息。

什麼是 IronPDF?

IronPDF 是一個強大的 .NET 庫,允許您 從 HTML 生成 PDF 文件 無論您需要創建發票、報告還是任何其他類型的文件,IronPDF 都提供一個易於使用的解決方案。它無縫整合到您的 ASP.NET Core 應用程序中,使您只需幾行代碼即可生成高品質的 PDF 文件。

使用 Fluent Validation 與 IronPDF

現在我們了解了什麼是 Fluent Validation 和 IronPDF,讓我們看看如何將它們一起使用。本教程將幫助建立一個發票生成器,其中發票內容將在使用 IronPDF 生成 PDF 之前,在 ASP.NET Core 中使用 FluentValidation 進行驗證。

現在讓我們開始吧!

設定專案

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

  1. 打開 Visual Studio 並前往 檔案 > 新建 > 專案
  2. 選擇「控制台應用程式」 (ASP.NET Core)「作為專案範本並為您的專案命名。」

    如何在C#中使用流暢驗證與IronPDF,圖1:創建一個新的控制台應用程序

    建立新的控制台應用程式

  3. 點擊下一步按鈕,透過命名並選擇存儲位置配置您的專案。

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

    配置新應用程式

  4. 點擊下一步按鈕並選擇.NET Framework。最新的.NET Framework (7) 推薦。

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

    .NET Framework 選擇

  5. 點擊 Create 按鈕來創建專案。

安裝必要的套件

專案建立後,我們需要添加 Fluent Validation 和 IronPDF 所需的 NuGet 套件。

  1. 在方案總管中右鍵點擊專案,選擇「管理 NuGet 套件」。
  2. 搜尋「FluentValidation」並點擊「安裝」以將該套件添加到您的專案中。

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

    安裝 FluentValidation 套件於 NuGet 套件管理器 UI

  3. 同樣地,搜尋"IronPDF"並安裝 IronPDF 套件。

然而,你也可以使用以下命令透過 NuGet 套件管理器控制台 安裝 IronPDF:

Install-Package IronPdf

如何在C#中使用流暢驗證與IronPDF,圖5:在包管理控制台中安裝IronPdf包

在套件管理員控制台中安裝 IronPdf 套件

在設置好專案並安裝所需套件後,讓我們繼續定義 PDF 內容類別。

定義 PDF 內容

在此範例中,將從新的兩個類別:InvoiceContentInvoiceItem 中的 HTML 代碼創建一個簡單的發票 PDF。

public abstract class PdfContent
{
    public abstract string RenderHtml();
}

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

    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; }
}
public abstract class PdfContent
{
    public abstract string RenderHtml();
}

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

    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; }
}
Public MustInherit Class PdfContent
	Public MustOverride Function RenderHtml() As String
End Class

Public Class InvoiceContent
	Inherits PdfContent

	Public Property CustomerName() As String
	Public Property Address() As String
	Public Property InvoiceItems() As List(Of InvoiceItem)

	Public Overrides Function RenderHtml() As String
		Dim invoiceItemsHtml As String = String.Join("", InvoiceItems.Select(Function(item) $"<li>{item.Description}: {item.Price}</li>"))
		Return $"<h1>Invoice for {CustomerName}</h1><p>{Address}</p><ul>{invoiceItemsHtml}</ul>"
	End Function
End Class

Public Class InvoiceItem
	Public Property Description() As String
	Public Property Price() As Decimal
End Class
VB   C#

在上面的代碼中,定義了一個抽象的 PdfContent 類別,其中包含名為 RenderHtml 的抽象方法。InvoiceContent 類別繼承了 PdfContent,並表示發票 PDF 的內容。它具有客戶名稱、地址和發票項目列表的屬性。InvoiceItem 類別包含兩個屬性「Description」和「Price」。RenderHtml 方法根據內容生成發票的 HTML 標記。

現在 PDF 內容已經定義好了,接下來我們來使用 Fluent Validation 創建驗證規則。

建立驗證規則

為了為 InvoiceContent 類別建立驗證規則,請建立一個名為 InvoiceContentValidator 的驗證器類別。此類別將繼承自 AbstractValidator`, 由 Fluent Validation 提供。

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.");
    }
}
Imports FluentValidation

Public Class InvoiceContentValidator
	Inherits AbstractValidator(Of InvoiceContent)

	Public Sub New()
		RuleFor(Function(content) content.CustomerName).NotEmpty().WithMessage("Customer name is required.")
		RuleFor(Function(content) content.Address).NotEmpty().WithMessage("Address is required.")
		RuleFor(Function(content) content.InvoiceItems).NotEmpty().WithMessage("At least one invoice item is required.")
		RuleForEach(Function(content) content.InvoiceItems).SetValidator(New InvoiceItemValidator())
	End Sub
End Class

Public Class InvoiceItemValidator
	Inherits AbstractValidator(Of InvoiceItem)

	Public Sub New()
		RuleFor(Function(item) item.Description).NotEmpty().WithMessage("Description is required.")
		RuleFor(Function(item) item.Price).GreaterThanOrEqualTo(0).WithMessage("Price must be greater than or equal to 0.")
	End Sub
End Class
VB   C#

在上面的源代碼中,定義了 InvoiceContentValidator 類,它繼承自 AbstractValidator在驗證器類別的構造函數內,RuleFor 方法為 InvoiceContent 類別的每個屬性定義驗證規則。

例如,RuleFor(內容 => 內容.客戶名稱)可以定義一個新規則,使客戶姓名不能為空。流暢驗證也可以鏈接NotEmpty` 方法來指定此驗證規則。同樣的,我們為地址和發票項目的屬性定義驗證規則。

要驗證發票項目,使用 RuleForEach 方法迭代 InvoiceItems 列表中的每個項目並應用名為 InvoiceItemValidator 的驗證器。InvoiceItemValidator 類是單獨定義的,包含 InvoiceItem 類的驗證規則。

設置這些驗證規則後,讓我們開始使用 IronPDF 生成 PDF。

使用 IronPDF 生成 PDF

IronPDF 是一個受歡迎的 .NET 庫,用於創建和操作 PDF 文件。將使用 IronPDF 根據驗證過的發票內容生成 PDF。

using IronPdf;
using FluentValidation;

public class PdfService
{
    public PdfDocument GeneratePdf<T>(T content) where T : PdfContent
    {
        var validator = GetValidatorForContent(content);
        FluentValidation.Results.ValidationResult validationResult = validator.Validate(content);

        if (!validationResult.IsValid)
        {
            throw new FluentValidation.ValidationException(validationResult.Errors);
        }

        var renderer = new ChromePdfRenderer();
        return renderer.RenderHtmlAsPdf(content.RenderHtml());
    }

    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
{
    public PdfDocument GeneratePdf<T>(T content) where T : PdfContent
    {
        var validator = GetValidatorForContent(content);
        FluentValidation.Results.ValidationResult validationResult = validator.Validate(content);

        if (!validationResult.IsValid)
        {
            throw new FluentValidation.ValidationException(validationResult.Errors);
        }

        var renderer = new ChromePdfRenderer();
        return renderer.RenderHtmlAsPdf(content.RenderHtml());
    }

    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.");
        }
    }
}
Imports IronPdf
Imports FluentValidation

Public Class PdfService
	Public Function GeneratePdf(Of T As PdfContent)(ByVal content As T) As PdfDocument
		Dim validator = GetValidatorForContent(content)
		Dim validationResult As FluentValidation.Results.ValidationResult = validator.Validate(content)

		If Not validationResult.IsValid Then
			Throw New FluentValidation.ValidationException(validationResult.Errors)
		End If

		Dim renderer = New ChromePdfRenderer()
		Return renderer.RenderHtmlAsPdf(content.RenderHtml())
	End Function

	Private Function GetValidatorForContent(Of T As PdfContent)(ByVal content As T) As IValidator(Of T)
		If TypeOf content Is InvoiceContent Then
			Return DirectCast(New InvoiceContentValidator(), IValidator(Of T))
		Else
			Throw New NotSupportedException("Unsupported content type.")
		End If
	End Function
End Class
VB   C#

在上面的源代碼中,我們定義了一個 PdfService 類別,提供了一個 GeneratePdf 方法。此方法接受一個 PdfContent 物件作為輸入,並根據驗證過的內容生成 PDF 文件。

首先,我們通過呼叫 GetValidatorForContent 方法來獲取適合的驗證器。此方法檢查內容的類型並返回相應的驗證器。在我們的情況下,我們僅支援 InvoiceContent 並使用 InvoiceContentValidator

接下來,我們使用驗證器通過呼叫其 validate 方法來驗證內容。驗證結果存儲在一個 ValidationResult 物件中。

如果驗證失敗 (!validationResult.IsValid)我們會拋出一個 FluentValidation.ValidationException,其中包含驗證錯誤。否則,我們將繼續使用 IronPDF 生成 PDF。

我們創建一個實例 ChromePdfRenderer 將 HTML 內容渲染為 PDF。我們稱之為 RenderHtmlAsPdfhtmlToPdf 物件上調用方法,並傳入由 content.RenderHtml 方法生成的 HTML。這樣就會生成 PDF 文件。

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

處理驗證錯誤

當發生驗證錯誤時,我們希望顯示錯誤消息並優雅地處理它。讓我們修改 Program 類別的 Main 方法以處理任何例外情況並向用戶顯示有意義的消息。

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
        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);
        }
    }
}
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
        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);
        }
    }
}
Public Class Program
	Shared Sub Main(ByVal args() As String)
		Dim pdfService As New PdfService()

		' Test 1: Empty Customer Name
		Try
			Dim invoiceContent As New InvoiceContent With {
				.CustomerName = "",
				.Address = "123 Main St, Anytown, USA",
				.InvoiceItems = New List(Of InvoiceItem) From {
					New InvoiceItem With {
						.Description = "Item 1",
						.Price = 19.99D
					},
					New InvoiceItem With {
						.Description = "Item 2",
						.Price = 29.99D
					}
				}
			}

			Dim pdfDocument = pdfService.GeneratePdf(invoiceContent)
			pdfDocument.SaveAs("C:\TestInvoice.pdf")
			Console.WriteLine("PDF generated successfully!")
		Catch ex As Exception
			Console.WriteLine("Error generating PDF: " & ex.Message)
		End Try

		' Test 2: Empty InvoiceItems
		Try
			Dim invoiceContent As New InvoiceContent With {
				.CustomerName = "John Doe",
				.Address = "123 Main St, Anytown, USA",
				.InvoiceItems = New List(Of InvoiceItem)()
			}

			Dim pdfDocument = pdfService.GeneratePdf(invoiceContent)
			pdfDocument.SaveAs("C:\TestInvoice.pdf")
			Console.WriteLine("PDF generated successfully!")
		Catch ex As Exception
			Console.WriteLine("Error generating PDF: " & ex.Message)
		End Try

		'Successful
		Try
			Dim invoiceContent As New InvoiceContent With {
				.CustomerName = "John Doe",
				.Address = "123 Main St, Anytown, USA",
				.InvoiceItems = New List(Of InvoiceItem) From {
					New InvoiceItem With {
						.Description = "Item 1",
						.Price = 19.99D
					},
					New InvoiceItem With {
						.Description = "Item 2",
						.Price = 29.99D
					}
				}
			}
			Dim pdfDocument = pdfService.GeneratePdf(invoiceContent)
			pdfDocument.SaveAs("C:\TestInvoice.pdf")
			Console.WriteLine("PDF generated successfully!")
		Catch ex As Exception
			Console.WriteLine("Error generating PDF: " & ex.Message)
		End Try
	End Sub
End Class
VB   C#

在上面的代碼中,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#中使用流暢驗證與IronPDF,圖7:輸出PDF文件

輸出 PDF 檔案

如預期所料,前兩個情境顯示了驗證錯誤,第三個情境顯示成功訊息。

結論

本教學探討了 Fluent Validation,並學習如何將其與 IronPDF 一起使用來生成 PDF 文件。從設置控制台應用程式和定義 PDF 內容類開始。然後,使用 Fluent Validation 創建驗證規則,並在不同的場景下測試 PDF 生成。

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

IronPDF 提供一個 免費試用 並且授權從 $749 開始。

< 上一頁
PDF與PDFA(開發人員的運作方式)
下一個 >
如何使用 ChatGPT 與 IronPDF 給 C# 開發者

準備開始了嗎? 版本: 2024.10 剛剛發布

免費 NuGet 下載 總下載次數: 10,993,239 查看許可證 >