Test dans un environnement réel
Test en production sans filigrane.
Fonctionne partout où vous en avez besoin.
FluentValidation est une bibliothèque de validation .NET qui permet de construire des règles de validation fortement typées. Pour ce faire, il fournit une interface fluide et des expressions lambda, ce qui rend le code plus lisible et plus facile à maintenir. Au lieu d'utiliser des annotations de données ou une validation manuelle dans vos classes de modèle, vous pouvez utiliser Fluent Validation pour construire une classe séparée pour votre logique de validation.
La validation fluide apporte plus de flexibilité au jeu de la validation. Avec des validateurs intégrés pour les scénarios courants, la possibilité de construire une validation personnalisée et un moyen simple d'enchaîner les règles de validation, Fluent Validation est un outil puissant dans la boîte à outils de .NET Core.
Fluent Validation est une bibliothèque open-source pour .NET qui facilite la construction de règles de validation pour vos classes de modèles.
**Les validateurs sont des classes qui encapsulent la logique de validation. Ils sont généralement créés en héritant de la classe AbstractValidator<T>
classe de base.
**Une règle est une condition de validation à laquelle une propriété doit satisfaire. Les règles sont définies à l'aide de la méthode RuleFor
dans une classe de validateur.
ValidationFailure
qui contient les détails de l'erreur, y compris le nom de la propriété et le message d'erreur.IronPDF est une puissante bibliothèque .NET qui vous permet de générer des documents PDF à partir de HTML le contenu. Que vous ayez besoin de créer des factures, des rapports ou tout autre type de document, IronPDF vous offre une solution facile à utiliser. Il s'intègre de manière transparente à vos applications ASP.NET Core, vous permettant de générer des fichiers PDF de haute qualité avec seulement quelques lignes de code.
Maintenant que nous avons compris ce que sont Fluent Validation et IronPDF, voyons comment ils peuvent être utilisés ensemble. Ce tutoriel aidera à construire un générateur de factures, où le contenu de la facture sera validé à l'aide de FluentValidation dans ASP.NET Core avant de générer le PDF à l'aide d'IronPDF.
Commençons maintenant!
Pour commencer, créons une nouvelle application console dans Visual Studio ou dans l'environnement de développement de votre choix.
Ouvrez Visual Studio et allez dans Fichier > Nouveau > Projet.
Sélectionnez "Console App (ASP.NET Core)"comme modèle de projet et donnez un nom à votre projet.
**Créer une nouvelle application console**
Cliquez sur le bouton Suivant et configurez votre projet en lui donnant un nom et en sélectionnant l'emplacement du dépôt.
**Configurer la nouvelle application**
Cliquez sur le bouton Suivant et sélectionnez le Framework .NET. La dernière version du Framework .NET (7) est recommandée.
**Sélection du Framework .NET**
Une fois le projet créé, nous devons ajouter les packages NuGet nécessaires pour Fluent Validation et IronPDF.
Cliquez avec le bouton droit de la souris sur le projet dans l'explorateur de solutions et sélectionnez "Manage NuGet Packages"
Recherchez "FluentValidation" et cliquez sur "Install" pour ajouter le paquetage à votre projet.
**Installer le package FluentValidation dans l'interface NuGet Package Manager**
De même, recherchez "IronPDF" et installez le paquet IronPDF.
Cependant, vous pouvez également installer IronPDF en utilisant NuGet Package Manager Console à l'aide de la commande suivante :
Install-Package IronPdf
Installez le paquet IronPDF dans la console du gestionnaire de paquets
Une fois le projet mis en place et les paquets nécessaires installés, passons à la définition de la classe de contenu PDF.
Dans cet exemple, une simple facture PDF sera créée à partir des codes HTML des deux nouvelles classes : InvoiceContent
et InvoiceItem
.
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
Dans le code ci-dessus, une classe abstraite PdfContent
est définie avec une méthode abstraite appelée RenderHtml
. La classe InvoiceContent
étend la classe PdfContent
et représente le contenu du PDF de la facture. Il comporte des propriétés pour le nom et l'adresse du client, ainsi qu'une liste des éléments de la facture. La classe InvoiceItem
contient deux propriétés 'Description' et 'Price'. La méthode RenderHtml
génère le balisage HTML de la facture en fonction du contenu.
Maintenant que le contenu du PDF est défini, passons à la création de règles de validation à l'aide de Fluent Validation.
Pour construire les règles de validation de la classe InvoiceContent
, créez une classe de validateur appelée InvoiceContentValidator
. Cette classe héritera de AbstractValidator<InvoiceContent>
, qui est fourni par 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
Dans le code source ci-dessus, la classe InvoiceContentValidator
est définie, qui hérite de AbstractValidator
. Dans le constructeur de la classe validator, la méthode
RuleFordéfinit les règles de validation pour chaque propriété de la classe
InvoiceContent`.
Par exemple, RuleFor(content => content.CustomerName)
peut définir une nouvelle règle selon laquelle le nom du client ne doit pas être vide. Fluent Validation peut également chaîner la méthode NotEmpty
pour spécifier cette règle de validation. De même, nous définissons des règles de validation pour les propriétés "adresse" et "éléments de la facture".
Pour valider les éléments de la facture, la méthode RuleForEach
est utilisée pour itérer sur chaque élément de la liste InvoiceItems
et appliquer un validateur appelé InvoiceItemValidator
. La classe InvoiceItemValidator
est définie séparément et contient des règles de validation pour la classe InvoiceItem
.
Une fois ces règles de validation en place, passons à la génération du PDF à l'aide d'IronPDF.
IronPDF est une bibliothèque .NET populaire pour la création et la manipulation de documents PDF. IronPDF sera utilisé pour générer le PDF sur la base du contenu validé de la facture.
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
Dans le code source ci-dessus, nous définissons une classe PdfService
qui fournit une méthode GeneratePdf
. Cette méthode prend en entrée un objet PdfContent
et génère le document PDF en fonction du contenu validé.
Tout d'abord, nous récupérons le validateur approprié pour le contenu en appelant la méthode GetValidatorForContent
. Cette méthode vérifie le type du contenu et renvoie le validateur correspondant. Dans notre cas, nous ne supportons que InvoiceContent
et utilisons le InvoiceContentValidator
.
Ensuite, nous validons le contenu à l'aide du validateur en appelant sa méthode validate. Le résultat de la validation est stocké dans un objet ValidationResult
.
Si la validation échoue (!validationResult.IsValid
)nous lançons une FluentValidation.ValidationException
avec les erreurs de validation. Dans le cas contraire, nous procédons à la génération du PDF à l'aide d'IronPDF.
Nous créons une instance de ChromePdfRenderer
pour rendre le contenu HTML sous forme de PDF. Nous appelons le RenderHtmlAsPdf
(RenduHtmlAsPdf) sur l'objet htmlToPdf
et lui passer le HTML généré par la méthode content.RenderHtml
. Cette opération génère le document PDF.
Maintenant que nous avons défini la logique de génération du PDF, gérons les éventuelles erreurs de validation.
Lorsqu'une erreur de validation se produit, nous voulons afficher un message d'erreur et la traiter avec élégance. Modifions la méthode Main
de la classe Program
pour gérer les exceptions et afficher des messages significatifs à l'utilisateur.
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
Dans le code ci-dessus, un bloc try-catch
permet d'attraper toutes les exceptions qui peuvent se produire. Si une exception est levée, un message d'erreur sera affiché à l'utilisateur en utilisant Console.WriteLine
.
Testons maintenant cette application avec différents scénarios pour valider la génération de PDF et les règles de validation.
Dans l'exemple de code, il y a trois scénarios à tester :
Nom du client vide : laissez le nom du client vide pour déclencher une erreur de validation.
Postes de facturation vides : Une liste vide de postes de facture est fournie pour déclencher une erreur de validation.
Génération réussie : Fournir un contenu valide pour générer le PDF avec succès.
Exécutez l'application et observez la sortie dans la console.
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!
**L'erreur de sortie dans la console
Le fichier PDF de sortie
Comme prévu, des erreurs de validation sont affichées pour les deux premiers scénarios et un message de réussite pour le troisième.
Ce tutoriel explore Fluent Validation et apprend à l'utiliser avec IronPDF pour générer des documents PDF. Commencez par configurer une application console et définissez la classe de contenu PDF. Ensuite, nous avons créé des règles de validation à l'aide de Fluent Validation et testé la génération de PDF avec différents scénarios.
Fluent Validation fournit une approche flexible et facile à utiliser pour valider les objets dans les applications .NET. Il permet de définir des règles de validation d'une manière fortement typée, de personnaliser les messages d'erreur et de traiter les erreurs de validation de manière élégante.
IronPDF offre une essai gratuit et la licence commence à partir de $749.
9 produits de l'API .NET pour vos documents de bureau