跳至頁尾內容
Iron Academy Logo
C#工具與生產力

在C#中的Fluent Validation - 強大且簡易的資料驗證工具

Tim Corey
43m 58s

資料驗證是可靠的軟體開發的支柱之一,在現代的.NET應用程式中,您需要一種穩健、可維護且可擴展的方式來處理它。 這就是FluentValidation的用武之地,它是一個流行的.NET程式庫,用於構建強型別的驗證規則。

在他深入的影片教程"Fluent Validation in C# – The Powerful Yet Easy Data Validation Tool",Tim Corey帶領觀眾逐步使用FluentValidation。在本文中,我們將按照Tim的演示進行,總結重點和程式碼範例,同時整合相關概念,如自訂驗證器、鏈式驗證器、ASP.NET整合以及對.NET Core 3.1和.NET Standard 2.0等舊版運行時的支援。

簡介:為什麼使用FluentValidation?

Tim在影片一開始解釋了資料驗證如何經常變得重複而混亂。 例如,將類似的驗證規則複製和粘貼到專案的不同部分中,違反了DRY(Don't Repeat Yourself)原則。 相反,他介紹了FluentValidation—一個免費的、強大的.NET驗證程式庫,即使是您不擁有的模型也可以使用,這使其成為商業專案的理想選擇。

Tim強調實踐您所學習到的重要性,並引導觀眾到他的週挑戰系列以建立技能。

演示應用程式概述

Tim使用一個WinForms演示應用程式,使用者可以輸入:

  • 賬戶餘額

  • 出生日期

雖然這是一個UI演示,但驗證原則同樣適用於ASP.NET Core、API測試,甚至是控制台應用程式。

信任使用者輸入的危險

在這一點上,Tim提醒開發者:"永遠不要相信使用者。"輸入通常是不可預測的,例如將"十"輸入為年齡而不是10。在將其保存到資料庫之前,驗證該輸入是必須的。

他列出了範例驗證規則:

  • 姓名和姓氏不應該是空的。

  • 賬戶餘額應遵循財務規則,例如財務贊助的最低要求。

  • 出生日期不應該是將來的或超過120歲。

驗證邏輯應該放在哪裡?

Tim探索了配置驗證器的選項:

  • 在UI表單內部

  • 使用資料註釋在模型類中

  • 使用FluentValidation在一個單獨的驗證類中

他指出資料註釋是有限的,通常不適合使用外部程式庫或需要更多自訂驗證邏輯時。

安裝FluentValidation

使用Visual Studio,Tim通過NuGet將FluentValidation新增到他的專案中。 他安裝了8.1.0版本,但指出FluentValidation是跨平台的,相容於:

  • .NET Standard 2.0

  • .NET Core

  • ASP.NET

  • WPF

  • Xamarin

  • 以及更多

Tim的設置也適用於需要支援較舊運行時的使用者,包括支援.NET Core 3.1及更早版本的FluentValidation 11。

建立驗證器類

Tim通過建立一個新類展示了如何構建強型別驗證規則:

public class PersonValidator : AbstractValidator<Person>
public class PersonValidator : AbstractValidator<Person>

此類包含Person模型的所有驗證邏輯。 使用fluent介面,驗證規則在建構函式中定義。

第一條驗證規則:名

Tim使用Lambda表達式編寫了一條規則:

RuleFor(p => p.FirstName).NotEmpty();
RuleFor(p => p.FirstName).NotEmpty();

他使用var validator來驗證Person物件:

var validator = new PersonValidator();
ValidationResult results = validator.Validate(person);
var validator = new PersonValidator();
ValidationResult results = validator.Validate(person);

然後他迴圈通過任何驗證失敗向量來在列表框中顯示使用者友好的資訊。

字串長度和自訂消息

Tim擴展了驗證規則:

RuleFor(p => p.FirstName)
    .NotEmpty().WithMessage("First name is empty")
    .Length(2, 50).WithMessage("Length of first name is invalid");
RuleFor(p => p.FirstName)
    .NotEmpty().WithMessage("First name is empty")
    .Length(2, 50).WithMessage("Length of first name is invalid");

使用連結驗證器,此規則確保名稱既不空也不太短/長。 Tim介紹了Cascade(CascadeMode.Stop)以在第一個失敗時停止驗證。

自訂驗證:名中的有效字元

Tim使用一個名為的方法實現了一個自訂驗證器:

private bool BeAValidName(string name)
private bool BeAValidName(string name)

這會剝除空格和破折號,並確保字串只包含Unicode字母,以支援國際字元。

自訂規通常這樣來應用:

.Must(BeAValidName).WithMessage("{PropertyName} contains invalid characters");
.Must(BeAValidName).WithMessage("{PropertyName} contains invalid characters");

此方法結構非常適合適應其他字段—例如,自訂郵編驗證邏輯功能:

private bool BeAValidPostcode(string postcode)
{
    // Add custom logic here to specify a valid postcode format
}
private bool BeAValidPostcode(string postcode)
{
    // Add custom logic here to specify a valid postcode format
}

然後,您可以在驗證器中這樣使用它:

RuleFor(c => c.Postcode).Must(BeAValidPostcode)
    .WithMessage("Please specify a valid postcode");
RuleFor(c => c.Postcode).Must(BeAValidPostcode)
    .WithMessage("Please specify a valid postcode");

這在需要公共類CustomerValidator或其他域特定驗證器的商業專案中很常見。

在錯誤資訊中使用內建變數

Tim展示了如何使用占位符(如)動態增強消息:

  • {PropertyName}

  • {TotalLength}

  • {MinLength}和{MaxLength}

這導致上下文錯誤消息如:

"Length of First Name is invalid (was 105)"
"Length of First Name is invalid (was 105)"

這使使用者更容易修正輸入錯誤。

姓和本地化

由於可重用格式與{PropertyName},Tim將FirstName驗證邏輯複製到LastName。 他還提到了WithLocalizedMessage(),適用於需要多語言支援的ASP.NET全球應用程式

重要事項:CascadeMode是規則特定的

Tim澄清了CascadeMode.Stop適用於個別規則,而不是整個模型的全域。 如果FirstName和LastName都為空,則兩個規則都將觸發——即使設置了CascadeMode。

出生日期驗證

接著,Tim新增了一條規則以確保出生日期是合理的:

private bool BeAValidAge(DateTime dob)
{
    var currentYear = DateTime.Now.Year;
    var dobYear = dob.Year;
    return dobYear <= currentYear && dobYear > (currentYear - 120);
}
private bool BeAValidAge(DateTime dob)
{
    var currentYear = DateTime.Now.Year;
    var dobYear = dob.Year;
    return dobYear <= currentYear && dobYear > (currentYear - 120);
}

這樣使用:

RuleFor(p => p.DateOfBirth)
    .Must(BeAValidAge)
    .WithMessage("Invalid {PropertyName}");
RuleFor(p => p.DateOfBirth)
    .Must(BeAValidAge)
    .WithMessage("Invalid {PropertyName}");

這是一個很好的樣式,用於驗證日期或到期視窗等時間資料。

最後的想法與建議

Tim總結了FluentValidation的主要優點:

  • 集中的驗証邏輯

  • 容易建立自定的驗証器

  • 相容.NET 5和更新的運行時以及舊版運行時

  • 支援複雜模型、列表和異步規則

  • 對於業餘愛好者和商業專案皆為理想

他鼓勵觀眾探索FluentValidation文件以獲取進階用法,包括巢狀規則、電子郵件屬性驗證等等。

結論

FluentValidation賦予.NET開發人員能夠構建可重用、表達性和可維護的強型別驗證規則。 無論您是在開發.NET Core、.NET 8,或是維護基於.NET Core 3.1的遺留系統,此程式庫都讓資料驗證簡單輕鬆。

其擁有的特性包括:

  • 用於構建規則的流暢介面

  • 支援自訂郵編驗證邏輯

  • 與Visual Studio的易整合性

  • 相容API測試、WinForms和ASP.NET

  • 對驗證失敗進行的強大處理

FluentValidation是您.NET工具包中的一個必備品。 想了解更多細節,請觀看完整影片,並訂閲Tim的頻道以獲取更多關於C#的洞見影片。

提示:如果您是FluentValidation的新手,嘗試實作您的CustomerValidator,定義屬性如public string Name, string Postcode等的規則。 用模擬API或UI表單測試來獲取實際操作經驗。

Hero Worlddot related to 在C#中的Fluent Validation - 強大且簡易的資料驗證工具
Hero Affiliate related to 在C#中的Fluent Validation - 強大且簡易的資料驗證工具

分享您所愛以賺取更多報酬

您是否為使用 .NET、C#、Java、Python 或 Node.js 的開發者建立內容?將您的專業知識轉化為額外收入!

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話