使用IRONPDF

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

更新 2024年三月17日
分享:

什么是流畅验证?

流畅验证 是一个 .NET 验证库,有助于构建强类型验证规则。它通过提供流畅的接口和 lambda 表达式,使代码更具可读性和可维护性。您可以使用 Fluent Validation 为您的验证逻辑建立一个单独的类,而不是在模型类中使用数据注解或手动验证。

Fluent Validation 为验证游戏带来了更多灵活性。Fluent Validation 具有适用于常见场景的内置验证器、构建自定义验证的能力以及连锁验证规则的简单方法,是 .NET Core 工具包中的一个强大工具。

了解流畅验证

Fluent Validation 是.NET 的一个开源库,可让您轻松为模型类构建验证规则。

  1. 验证器: 验证器是封装验证逻辑的类。它们通常通过继承自 `AbstractValidator基类。

  2. 规则: 规则是属性必须满足的验证条件。规则是使用验证器类中的 RuleFor 方法定义的。

  3. 验证失败: 如果规则失败,Fluent Validation 会创建一个 ValidationFailure 对象,其中包含错误的详细信息,包括属性名称和错误信息。

什么是 IronPDF?

IronPDF 是一个功能强大的 .NET 库,可让您 从 HTML 生成 PDF 文档 内容。无论您需要创建发票、报告或任何其他类型的文档,IronPDF 都能为您提供简单易用的解决方案。它与您的 ASP.NET Core 应用程序无缝集成,只需几行代码就能生成高质量的 PDF 文件。

使用 IronPDF 进行流体验证

既然我们已经了解了什么是 Fluent Validation 和 IronPDF,那就让我们来看看如何将它们结合起来使用。本教程将帮助创建一个发票生成器,在使用 IronPDF 生成 PDF 之前,先使用 ASP.NET Core 中的 FluentValidation 验证发票内容。

现在开始!

设置项目

首先,让我们在 Visual Studio 或你喜欢的开发环境中创建一个新的控制台应用程序。

1.打开 Visual Studio,进入 文件 > 新建 > 项目

2.选择 "控制台应用程序 (ASP.NET Core)"作为项目模板,并提供项目名称。

![如何在 C# 中使用 IronPDF 的流畅验证,图 1:创建一个新的控制台应用程序](/static-assets/pdf/blog/fluent-validation-csharp/fluent-validation-csharp-1.webp)

**创建新的控制台应用程序**

3.点击 "下一步 "*** 按钮,通过给出名称和选择版本库位置来配置项目。

![如何在 C# 中使用 IronPDF 进行流畅验证,图 2:配置新应用程序](/static-assets/pdf/blog/fluent-validation-csharp/fluent-validation-csharp-2.webp)

**配置新应用程序**

4.单击下一步按钮,选择 .NET Framework。最新的 .NET Framework (7) 建议

![如何在 C# 中使用 IronPDF 的流畅验证,图 3:.NET 框架选择](/static-assets/pdf/blog/fluent-validation-csharp/fluent-validation-csharp-3.webp)

**.NET框架选择**

5.点击创建按钮创建项目。

安装所需软件包

创建项目后,我们需要为 Fluent Validation 和 IronPDF 添加必要的 NuGet 软件包。

1.右键单击解决方案资源管理器中的项目,选择 "管理 NuGet 包"。

2.搜索 "FluentValidation",然后点击 "安装 "将软件包添加到项目中。

![图 4:在 NuGet 软件包管理器 UI 中安装 FluentValidation 软件包](/static-assets/pdf/blog/fluent-validation-csharp/fluent-validation-csharp-4.webp)

**在 NuGet 软件包管理器用户界面安装 FluentValidation 软件包**

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 "的抽象方法。发票内容 "类扩展了 "PDFContent",代表 PDF 格式发票的内容。它具有客户名称、地址和发票项目列表的属性。发票项目 "类包含两个属性 "描述 "和 "价格"。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<InvoiceContent>.在验证器类的构造函数中,"RuleFor "方法为 "InvoiceContent "类的每个属性定义了验证规则。

例如,RuleFor(content => content.CustomerName)可以定义一条新规则,即客户名称不能为空。Fluent Validation 还可以链式使用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#

在上面的源代码中,我们定义了一个提供 GeneratePdf 方法的 PdfService 类。该方法将 PdfContent 对象作为输入,并根据验证后的内容生成 PDF 文档。

首先,我们通过调用 GetValidatorForContent 方法为内容获取相应的验证器。该方法会检查内容的类型并返回相应的验证器。在本例中,我们只支持 InvoiceContent 并使用 InvoiceContentValidator

接下来,我们通过调用验证器的 validate 方法来验证内容。验证结果存储在一个 ValidationResult 对象中。

如果验证失败 (!validationResult.IsValid.)否则,我们会抛出一个包含验证错误的 `FluentValidation.ValidationException'。否则,我们将使用 IronPDF 生成 PDF。

我们创建一个 ChromePdfRenderer 将 HTML 内容渲染为 PDF 格式。我们将 将Html渲染为Pdf 对象上的 htmlToPdf 方法,并传入由 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# 中使用 IronPDF 进行流畅验证,图 6:控制台中的输出错误

控制台输出错误

图 7:输出 PDF 文件

输出 PDF 文件

不出所料,前两种情况会显示验证错误,第三种情况会显示成功信息。

结论

本教程探讨了 Fluent Validation,并学习了如何将其与 IronPDF 结合使用以生成 PDF 文档。首先,设置控制台应用程序并定义 PDF 内容类。然后,使用 Fluent Validation 创建验证规则,并在不同场景下测试 PDF 的生成。

Fluent Validation 为在 .NET 应用程序中验证对象提供了一种灵活易用的方法。它允许你以强类型的方式定义验证规则,自定义错误信息,并优雅地处理验证错误。

IronPDF 提供了 免费试用 许可证从 $749 开始。

< 前一页
PDF与PDFA(开发者如何使用)
下一步 >
如何在C#开发中将ChatGPT与IronPDF结合使用

准备开始了吗? 版本: 2024.10 刚刚发布

免费NuGet下载 总下载量: 11,108,738 查看许可证 >