使用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 - 用 C# 将 HTML 转换为 PDF该工具是一个功能强大的 .NET 库,可让您从 HTML 内容生成 PDF 文档。 无论您需要创建发票、报告还是其他任何类型的文档,IronPDF 都能为您提供简单易用的解决方案。 它与您的 ASP.NET Core 应用程序无缝集成,只需几行代码就能生成高质量的 PDF 文件。

使用 IronPDF 进行流畅验证

现在我们了解了什么是流畅验证和 IronPDF,让我们来看看如何将它们结合起来使用。 本教程将帮助构建一个发票生成器,在使用 IronPDF for .NET 生成 PDF 之前,将使用 ASP.NET Core 中的 FluentValidation 对发票内容进行验证。

现在开始!

设置项目

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

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

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

    如何在 C# 中使用 IronPDF 的流畅验证,图 1:创建一个新的控制台应用程序

    创建一个新的控制台应用程序

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

    如何在 C# 中使用 IronPDF 进行流畅验证,图 2:配置新应用程序

    配置新应用程序

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

    如何在 C# 中使用 IronPDF 的流畅验证,图 3:.NET 框架选择

    *.NET Framework 选择***

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

安装所需的软件包

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

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

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

    图 4:在 NuGet 软件包管理器 UI 中安装 FluentValidation 软件包

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

  3. 同样,搜索"IronPDF - 强大的 .NET PDF 库"并安装 IronPDF 软件包。

    不过,您也可以使用 NuGet 软件包管理器控制台,使用以下命令安装 IronPdf:

Install-Package IronPdf

如何在 C# 中使用 IronPDF 进行流畅验证,图 5:在软件包管理器控制台中安装 IronPdf 软件包

在软件包管理器控制台中安装 IronPdf 软件包

在项目设置和所需软件包安装完成后,让我们继续定义 PDF 内容类。

定义 PDF 内容

在本示例中,将根据新的两个类:"InvoiceContent "和 "InvoiceItem "中的 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 格式发票的内容。 它具有客户名称、地址和发票项目列表的属性。 发票项目 "类包含两个属性 "描述 "和 "价格"。 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 - 生成和编辑 PDF 文档PDF 是一个流行的 .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 方法,并传入由 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 免费试用版和许可信息该翻译工具提供免费试用,每位开发人员的许可证费用从 499 美元起。

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

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

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