IRONPDFの使用

IronPDFを使用したC#でのFluent Validationの方法

フルーエントバリデーションとは何ですか?

FluentValidationは、厳密に型指定されたバリデーションルールの構築を支援する.NETバリデーションライブラリです。 これは流暢なインターフェースとラムダ式を提供することで実現され、コードをより読みやすく、保守しやすくします。 モデルクラスでデータ注釈や手動検証を使用する代わりに、Fluent Validation を使用して検証ロジック用の別のクラスを作成できます。

Fluent Validationは、バリデーションの分野により柔軟性をもたらします。 組み込みのバリデーターで一般的なシナリオに対応し、カスタムバリデーションを構築する能力、そしてバリデーションルールをチェーンする簡単な方法を備えたFluent Validationは、.NET Coreツールキットの強力なツールです。

流暢なバリデーションの理解

Fluent Validationは、モデルクラスのバリデーションルールを簡単に構築できるオープンソースの.NETライブラリです。

  1. 検証ツール: 検証ツールは、検証ロジックをカプセル化するクラスです。 それらは通常、AbstractValidator<T> 基底クラスから継承することによって作成されます。

  2. ルール: ルールは、プロパティが満たさなければならない検証条件です。 ルールはバリデータークラス内のRuleForメソッドを使用して定義されます。

  3. 検証の失敗: ルールが失敗した場合、Fluent Validation は、プロパティ名やエラーメッセージを含むエラーの詳細を含む ValidationFailure オブジェクトを作成します。

IronPDFとは何ですか?

IronPDF - C#でHTMLをPDFに変換 は、HTMLコンテンツからPDFドキュメントを生成できる強力な.NETライブラリです。 請求書、レポート、その他どのような種類のドキュメントを作成する必要がある場合でも、IronPDFは使いやすいソリューションを提供します。 それは、ASP.NET Core アプリケーションとシームレスに統合され、わずか数行のコードで高品質なPDFファイルを生成できます。

IronPDFでFluent Validationを使用する

では、Fluent ValidationとIronPDFがどのようなものか理解したところで、それらを一緒に使用する方法を見てみましょう。 このチュートリアルでは、請求書生成ツールを構築する際に、FluentValidationを使用してASP.NET Coreで請求書の内容が検証され、IronPDFを使用してPDFを生成する方法を紹介します。

それでは始めましょう!

プロジェクトの設定

まずは、Visual Studio またはお好みの開発環境で新しいコンソールアプリケーションを作成しましょう。

  1. Visual Studio を開き、ファイル > 新規作成 > プロジェクト に移動します。

  2. プロジェクトテンプレートとして「Console App (ASP.NET Core)」を選択し、プロジェクト名を指定します。

    IronPDFでFluent ValidationをC#で使用する方法、図1: 新しいコンソールアプリケーションを作成

    新しいコンソールアプリケーションを作成する

  3. 次へ ボタンをクリックし、名前を付けてリポジトリの場所を選択してプロジェクトを設定します。

    IronPDFでFluent ValidationをC#で使用する方法、図2: 新しいアプリケーションの設定

    新しいアプリケーションを設定する

  4. 次へボタンをクリックし、.NET Frameworkを選択します。 最新の.NET Framework(7)が推奨されます。

    IronPDFでのFluent Validationの使用方法(C#)、図3: .NET Frameworkの選択

    .NET Frameworkの選択

  5. 作成ボタンをクリックしてプロジェクトを作成します。

必要なパッケージをインストール

プロジェクトが作成されたら、Fluent ValidationおよびIronPDFの必要なNuGetパッケージを追加する必要があります。

  1. ソリューションエクスプローラーでプロジェクトを右クリックし、「NuGet パッケージの管理」を選択します。

  2. 「FluentValidation」を検索し、「インストール」をクリックしてパッケージをプロジェクトに追加します。

    C#でIronPDFを使用したFluent Validationの方法、図4: NuGetパッケージマネージャーUIでFluentValidationパッケージをインストール

    NuGet パッケージ マネージャー UI で FluentValidation パッケージをインストールする

  3. 同様に、「IronPDF - Powerful .NET PDF Library」を検索し、IronPDFパッケージをインストールします。

    ただし、次のコマンドを使用してNuGet パッケージ マネージャ コンソールを使用してIronPDFをインストールすることもできます:

Install-Package IronPdf

IronPDFを使用したFluent Validationの利用方法, 図5: パッケージ マネージャー コンソールでIronPdfパッケージをインストールする

パッケージ マネージャー コンソールにIronPdfパッケージをインストールする

プロジェクトのセットアップと必要なパッケージのインストールが完了したら、PDFコンテンツクラスの定義に進みましょう。

PDFコンテンツの定義

この例では、新しい 2 つのクラス: 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
$vbLabelText   $csharpLabel

上記のコードでは、RenderHtmlという名前の抽象メソッドを持つ抽象PdfContentクラスが定義されています。 InvoiceContent クラスは PdfContent を拡張し、請求書PDFの内容を表します。 顧客名、住所、および請求書項目のリストに関するプロパティがあります。 InvoiceItemクラスには、'Description'と'Price'の2つのプロパティが含まれています。 RenderHtml メソッドは、コンテンツに基づいて請求書のHTMLマークアップを生成します。

PDFコンテンツが定義されたので、Fluent Validationを使って検証ルールの作成に進みましょう。

検証ルールの作成

InvoiceContent クラスの検証ルールを構築するために、InvoiceContentValidator と呼ばれるバリデータークラスを作成してください。 このクラスは、Fluent Validation によって提供される 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.");
    }
}
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
$vbLabelText   $csharpLabel

上記のソースコードでは、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ライブラリです。 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
$vbLabelText   $csharpLabel

上記のソースコードでは、PdfService クラスを定義し、GeneratePdf メソッドを提供しています。 このメソッドはPdfContentオブジェクトを入力として受け取り、検証された内容に基づいてPDFドキュメントを生成します。

まず、GetValidatorForContent メソッドを呼び出して、コンテンツに適したバリデーターを取得します。 このメソッドはコンテンツのタイプをチェックし、対応するバリデーターを返します。 私たちの場合、InvoiceContent のみをサポートし、InvoiceContentValidator を使用します。

次に、バリデータのvalidateメソッドを呼び出してコンテンツを検証します。 検証結果はValidationResultオブジェクトに格納されます。

検証が失敗した場合(!validationResult.IsValid)、検証エラーとともにFluentValidation.ValidationExceptionをスローします。 それ以外の場合は、IronPDFを使用してPDFを生成します。

HTMLコンテンツをPDFとしてレンダリングするために、ChromePdfRendererのインスタンスを作成します。 私たちはRenderHtmlAsPdfメソッドを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
$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!

IronPDFでFluent ValidationをC#で使用する方法, 図6: コンソールでの出力エラー

コンソールでの出力エラー

IronPDFでFluent ValidationをC#で使用する方法、図7: 出力PDFファイル

出力PDFファイル

予想通り、最初の二つのシナリオでは検証エラーが表示され、三つ目のシナリオでは成功メッセージが表示されます。

結論

このチュートリアルでは、Fluent Validationを調査し、IronPDFを使用してPDF文書を生成する方法を学びました。 コンソールアプリケーションを設定し、PDFコンテンツクラスを定義することから始めます。 次に、Fluent Validationを使用して検証ルールを作成し、さまざまなシナリオでPDF生成をテストしました。

Fluent Validationは、.NETアプリケーションにおけるオブジェクトのバリデーションに対して柔軟で使いやすいアプローチを提供します。 強く型付けされた方法で検証ルールを定義し、エラーメッセージをカスタマイズし、検証エラーを優雅に処理することができます。

IronPDF Free Trial & Licensing Informationは無料試用版を提供しており、ライセンスは開発者1人あたり$499から始まります。

チペゴ
ソフトウェアエンジニア
チペゴは優れた傾聴能力を持ち、それが顧客の問題を理解し、賢明な解決策を提供する助けとなっています。彼は情報技術の学士号を取得後、2023年にIron Softwareチームに加わりました。現在、彼はIronPDFとIronOCRの2つの製品に注力していますが、顧客をサポートする新しい方法を見つけるにつれて、他の製品に関する知識も日々成長しています。Iron Softwareでの協力的な生活を楽しんでおり、さまざまな経験を持つチームメンバーが集まり、効果的で革新的な解決策を提供することに貢献しています。チペゴがデスクを離れているときは、良い本を楽しんだり、サッカーをしていることが多いです。
< 以前
PDF vs PDFA(開発者のための仕組み)
次へ >
C#開発者向けIronPDFでChatGPTを利用する方法