跳至页脚内容
使用IRONPDF

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

什么是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 - 在C#中将HTML转换为PDF是一个强大的.NET库,允许您从HTML内容生成PDF文档。 无论您需要创建发票、报告或其他类型的文档,IronPDF都提供了一种易于使用的解决方案。 它无缝集成到ASP.NET Core应用程序中,使您可以仅用几行代码生成高质量的PDF文件。

在IronPDF中使用Fluent Validation

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

项目设置

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

  1. 打开Visual Studio并转到文件 > 新建 > 项目
  2. 选择"控制台应用程序(ASP.NET Core)"作为项目模板,并为您的项目提供一个名称。

如何在C#中使用Fluent Validation与IronPDF,图1:创建新的控制台应用程序 创建新的控制台应用程序

  1. 点击下一步按钮,并通过命名并选择存储库位置来配置您的项目。

如何在C#中使用Fluent Validation与IronPDF,图2:配置新应用程序 配置新应用程序

  1. 点击下一步按钮并选择.NET Framework。 推荐使用最新的.NET Framework(7)。

如何在C#中使用Fluent Validation与IronPDF,图3:.NET Framework选择 .NET Framework 选择

  1. 点击创建按钮以创建项目。

安装所需包

项目创建完成后,添加Fluent Validation和IronPDF所需的NuGet包。

  1. 右键点击解决方案资源管理器中的项目并选择"管理NuGet包"。
  2. 搜索"FluentValidation"并点击"安装"以将包添加到您的项目中。

如何在C#中使用Fluent Validation与IronPDF,图4:在NuGet包管理器UI中安装FluentValidation包 在NuGet包管理器UI中安装FluentValidation包

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

或者,您可以使用NuGet包管理器控制台通过以下命令安装IronPDF:

Install-Package IronPdf

如何在C#中使用Fluent Validation与IronPDF,图5:在包管理器控制台中安装IronPdf包 在包管理器控制台中安装IronPdf包

在设置好项目并安装所需包后,让我们继续定义PDF内容类。

定义PDF内容

在这个例子中,将从两个类中的HTML代码中创建一个简单的发票PDF:InvoiceContentInvoiceItem

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类,其内部定义了一个抽象方法RenderHtmlInvoiceContent类扩展了PdfContent,表示发票PDF的内容。 它具有客户姓名、地址和发票项目列表的属性。 InvoiceItem类包含两个属性:'Description'和'Price'。 RenderHtml方法根据内容生成发票的HTML标记。

既然PDF内容已定义,让我们继续使用Fluent Validation创建验证规则。

创建验证规则

InvoiceContent类构建验证规则,请创建一个名为InvoiceContentValidator的验证器类。 该类将继承自FluentValidation提供的AbstractValidator<InvoiceContent>

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 => 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。 否则,使用IronPDF生成PDF。

创建< a href="/object-reference/api/IronPdf.ChromePdfRenderer.html">ChromePdfRenderer实例来将HTML内容渲染为PDF。 在renderer对象上调用< a href="/object-reference/api/IronPdf.ChromePdfRenderer.html# IronPdf_ChromePdfRenderer_RenderHtmlAsPdf_System_String_System_String_SystemString">RenderHtmlAsPdf方法,传入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 Free Trial & Licensing Information提供免费试用,许可证起价为每位开发者$499。

常见问题解答

如何在 C# 中集成 Fluent Validation 与 PDF 生成?

要在 C# 中集成 Fluent Validation 与 PDF 生成,您可以在 Visual Studio 中设置一个控制台应用程序,通过 NuGet 安装 FluentValidation 和 IronPDF 包,并在生成 PDF 时使用 Fluent Validation 定义模型验证逻辑。

设置用于 PDF 生成和验证的项目所涉及的步骤是什么?

要设置项目,请在 Visual Studio 中创建一个新的控制台应用程序,通过 NuGet 安装 IronPDF 和 FluentValidation 包,然后使用相关库定义您的 PDF 内容和验证规则。

如何使用 .NET 库从 HTML 内容生成 PDF?

您可以使用 IronPDF 的 RenderHtmlAsPdf 方法从 HTML 内容生成 PDF,它允许您将 HTML 字符串或文件转换为高质量的 PDF。

教程中 PdfService 类的目的是什么?

教程中的 PdfService 类旨在通过先使用 Fluent Validation 验证内容来管理 PDF 生成。在成功验证后,它使用 IronPDF 的 ChromePdfRendererRenderHtmlAsPdf 方法创建 PDF。

如何使用 Fluent Validation 定义验证规则?

Fluent Validation 中的验证规则是通过创建继承自 AbstractValidator<T> 的验证类来定义的。在此类中,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
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。