在实际环境中测试
在生产中测试无水印。
随时随地为您服务。
流畅验证 是一个 .NET 验证库,有助于构建强类型验证规则。它通过提供流畅的接口和 lambda 表达式,使代码更具可读性和可维护性。您可以使用 Fluent Validation 为您的验证逻辑建立一个单独的类,而不是在模型类中使用数据注解或手动验证。
Fluent Validation 为验证游戏带来了更多灵活性。Fluent Validation 具有适用于常见场景的内置验证器、构建自定义验证的能力以及连锁验证规则的简单方法,是 .NET Core 工具包中的一个强大工具。
Fluent Validation 是.NET 的一个开源库,可让您轻松为模型类构建验证规则。
验证器: 验证器是封装验证逻辑的类。它们通常通过继承自 `AbstractValidator
规则: 规则是属性必须满足的验证条件。规则是使用验证器类中的 RuleFor
方法定义的。
ValidationFailure
对象,其中包含错误的详细信息,包括属性名称和错误信息。IronPDF 是一个功能强大的 .NET 库,可让您 从 HTML 生成 PDF 文档 内容。无论您需要创建发票、报告或任何其他类型的文档,IronPDF 都能为您提供简单易用的解决方案。它与您的 ASP.NET Core 应用程序无缝集成,只需几行代码就能生成高质量的 PDF 文件。
既然我们已经了解了什么是 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
在软件包管理器控制台安装 IronPdf 软件包
完成项目设置和所需软件包的安装后,让我们继续定义 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
在上述代码中,定义了一个抽象的 "PDFContent "类,该类有一个名为 "RenderHtml "的抽象方法。发票内容 "类扩展了 "PDFContent",代表 PDF 格式发票的内容。它具有客户名称、地址和发票项目列表的属性。发票项目 "类包含两个属性 "描述 "和 "价格"。RenderHtml "方法根据内容生成发票的 HTML 标记。
现在,PDF 内容已经定义,让我们继续使用 Fluent Validation 创建验证规则。
要为 InvoiceContent
类创建验证规则,请创建一个名为 InvoiceContentValidator
的验证器类。该类将继承自 `AbstractValidator
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
在上述源代码中,定义了 InvoiceContentValidator
类,该类继承自 AbstractValidator<InvoiceContent>
.在验证器类的构造函数中,"RuleFor "方法为 "InvoiceContent "类的每个属性定义了验证规则。
例如,RuleFor(content => content.CustomerName)可以定义一条新规则,即客户名称不能为空。Fluent Validation 还可以链式使用
NotEmpty` 方法来指定此验证规则。同样,我们也为地址和发票项目属性定义了验证规则。
为了验证发票项目,我们使用 RuleForEach
方法遍历 InvoiceItems
列表中的每个项目,并应用名为 InvoiceItemValidator
的验证器。InvoiceItemValidator "类是单独定义的,包含 "InvoiceItem "类的验证规则。
有了这些验证规则,我们就可以使用 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
在上面的源代码中,我们定义了一个提供 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
在上面的代码中,"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!
控制台输出错误
输出 PDF 文件
不出所料,前两种情况会显示验证错误,第三种情况会显示成功信息。
本教程探讨了 Fluent Validation,并学习了如何将其与 IronPDF 结合使用以生成 PDF 文档。首先,设置控制台应用程序并定义 PDF 内容类。然后,使用 Fluent Validation 创建验证规则,并在不同场景下测试 PDF 的生成。
Fluent Validation 为在 .NET 应用程序中验证对象提供了一种灵活易用的方法。它允许你以强类型的方式定义验证规则,自定义错误信息,并优雅地处理验证错误。