跳過到頁腳內容
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提醒開發人員:"永遠不要信任使用者。"輸入常常是不可預測的,比如年齡鍵入"ten"而不是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模型的所有驗證邏輯。 使用流暢界面,在構造函數內定義驗證規則。

第一個驗證規則:名字

Tim使用lambda表達式編寫了一個規則:

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

他使用var驗證器來驗證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,為屬性如公共字串名稱、字串郵遞區號等制定規則。 通過模擬API或UI表單測試,獲取實踐經驗。

Hero Worlddot related to C#中的Fluent Validation - 強大而簡單的數據驗證工具
Hero Affiliate related to C#中的Fluent Validation - 強大而簡單的數據驗證工具

通過分享您所愛的東西賺得更多

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

鋼鐵支援團隊

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