Fluent Validation w C# - Potężne, a jednocześnie proste narzędzie do walidacji danych
Walidacja danych jest jednym z filarów niezawodnego rozwoju oprogramowania, a w nowoczesnych aplikacjach .NET potrzebujesz solidnego, łatwego w utrzymaniu i skalowalnego sposobu na jej obsługę. Właśnie tu wkracza FluentValidation, popularna biblioteka .NET do tworzenia silnie typowanych reguł walidacji.
W swoim szczegółowym wideoporadniku "Fluent Validation w C# – Potężne i łatwe narzędzie do walidacji danych", Tim Corey prowadzi widzów przez proces używania FluentValidation krok po kroku. W tym artykułe śledzimy przewodnik Tima, podsumowując kluczowe punkty i przykłady kodu, jednocześnie integrując istotne koncepcje, takie jak niestandardowe walidatory, łączenie walidatorów, integracja z ASP.NET oraz wsparcie dla starszych środowisk, takich jak .NET Core 3.1 i .NET Standard 2.0.
Wprowadzenie: Dłączego FluentValidation?
Tim rozpoczyna wideo, wyjaśniając, jak walidacja danych często staje się powtarzalna i chaotyczna. Na przykład, kopiowanie i wklejanie podobnych reguł walidacyjnych w różnych częściach projektu narusza zasadę DRY (Don't Repeat Yourself). Zamiast tego, wprowadza FluentValidation — bibliotekę walidacyjną .NET, która jest darmowa, potężna i działa nawet na modelach, które nie są twoje, co czyni ją idealną dla projektów komercyjnych.
Tim podkreśla znaczenie praktykowania tego, czego się uczysz i wskazuje widzom swoją serię Weekly Challenge jako sposób na rozwijanie umiejętności.
Przegląd Aplikacji Demo
Tim używa aplikacji demonstracyjnej WinForms, w której użytkownik może wprowadzić:
-
Imię
-
Nazwisko
-
Saldo konta
- Datę urodzenia
Chociaż to demo UI, zasady walidacji mają równie dobre zastosowanie w ASP.NET Core, testowaniu API, a nawet w aplikacjach konsolowych.
Niebezpieczeństwo Zaufania Wejściom Użytkownika
Na tym etapie, Tim przypomina programistom: "Nigdy nie ufaj użytkownikowi." Wejście może być często nieprzewidywalne, na przykład wpisanie "dziesięć" zamiast 10. Walidacja takiego wejścia jest niezbędna przed zapisaniem do bazy danych.
Przedstawia przykładowe reguły walidacji:
-
Imiona i nazwiska nie powinny być puste.
-
Saldo konta powinno podlegać regułom finansowym, jak na przykład minimalne wymagania dla sponsorowania finansowego.
- Data urodzenia nie powinna być w przyszłości ani być starsza niż 120 lat.
Gdzie Powinna Znajdować się Logika Walidacji?
Tim bada opcje konfigurowania walidatorów:
-
Wewnątrz formularza UI
-
W klasie modelu, korzystając z adnotacji danych
- W oddzielnej klasie walidacyjnej, używając FluentValidation
Zaznacza, że adnotacje danych są ograniczone i często nieodpowiednie, gdy pracuje się z zewnętrznymi bibliotekami lub potrzeba bardziej niestandardowej logiki walidacji.
Instalowanie FluentValidation
Korzystając z Visual Studio, Tim dodaje FluentValidation do swojego projektu za pośrednictwem NuGet. Instaluje wersję 8.1.0, ale zauważa, że FluentValidation jest wielopłatformowe i kompatybilne z:
-
.NET Standard 2.0
-
.NET Core
-
ASP.NET
-
WPF
-
Xamarin
- I inne
Konfiguracja Tima działa również dla tych, którzy potrzebują wsparcia dla starszych środowisk, w tym FluentValidation 11, które obsługuje .NET Core 3.1 i wcześniejsze.
Tworzenie Klasy Walidatora
Tim pokazuje tworzenie silnie typowanych reguł walidacji poprzez stworzenie nowej klasy:
public class PersonValidator : AbstractValidator<Person>
public class PersonValidator : AbstractValidator<Person>
Ta klasa zawiera całą logikę walidacji dla modelu Person. Korzystając z płynnego interfejsu, reguły walidacji są definiowane wewnątrz konstruktora.
Pierwsza Reguła Walidacji: Imię
Tim pisze regułę, używając wyrażenia lambda:
RuleFor(p => p.FirstName).NotEmpty();
RuleFor(p => p.FirstName).NotEmpty();
Używa var validator do walidacji obiektu Person:
var validator = new PersonValidator();
ValidationResult results = validator.Validate(person);
var validator = new PersonValidator();
ValidationResult results = validator.Validate(person);
Następnie przechodzi przez wszelkie błędy walidacji, aby wyświetlić przyjazne dla użytkownika komunikaty w polu listy.
Długość Ciągu i Niestandardowe Wiadomości
Tim rozwija regułę walidacji:
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");
Korzystając z łączenia walidatorów, ta reguła zapewnia, że imię nie jest ani puste, ani zbyt krótkie/długie. Tim wprowadza Cascade(CascadeMode.Stop), aby zatrzymać walidację przy pierwszej awarii.
Niestandardowa Walidacja: Prawidłowe Znaki w Imionach
Tim implementuje niestandardowy walidator przy użyciu metody o nazwie:
private bool BeAValidName(string name)
private bool BeAValidName(string name)
To usuwa spacje i kreski oraz zapewnia, że ciąg zawiera jedynie litery Unicode, umożliwiając wsparcie dla międzynarodowych znaków.
Niestandardowa reguła jest stosowana w ten sposób:
.Must(BeAValidName).WithMessage("{PropertyName} contains invalid characters");
.Must(BeAValidName).WithMessage("{PropertyName} contains invalid characters");
Ta struktura metody jest doskonała do dostosowywania do innych pól — na przykład niestandardowej funkcji walidacji kodu pocztowego:
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
}
Możesz ją następnie użyć w walidatorze, takim jak:
RuleFor(c => c.Postcode).Must(BeAValidPostcode)
.WithMessage("Please specify a valid postcode");
RuleFor(c => c.Postcode).Must(BeAValidPostcode)
.WithMessage("Please specify a valid postcode");
To jest powszechne w projektach komercyjnych wymagających publicznej klasy CustomerValidator lub innych walidatorów specyficznych dla domeny.
Używanie Wbudowanych Zmiennych w Komunikatach o Błędach
Tim pokazuje, jak dynamicznie ulepszać komunikaty za pomocą miejsc zastępczych takich jak:
-
{PropertyName}
-
{TotalLength}
- {MinLength} i {MaxLength}
To skutkuje kontekstowymi komunikatami o błędach, jak:
"Length of First Name is invalid (was 105)"
"Length of First Name is invalid (was 105)"
To ułatwia użytkownikom naprawianie błędów wejściowych.
Nazwisko i Lokalizacja
Tim kopiuje logikę walidacji FirstName dla LastName, dzięki możliwośćom ponownego użycia formatowania z {PropertyName}. Wspomina także o WithLocalizedMessage() dla ASP.NET lub globalnych aplikacji, które potrzebują wsparcia dla wielu języków.
Ważne: CascadeMode Jest Specyficzny dla Reguł
Tim wyjaśnia, że CascadeMode.Stop dotyczy indywidualnych reguł, a nie globalnie dla całego modelu. Jeśli zarówno FirstName, jak i LastName są puste, obie reguły zostaną wyzwolone — nawet jeśli CascadeMode jest ustawiony.
Walidacja Daty Urodzenia
Następnie Tim dodaje regułę, aby upewnić się, że data urodzenia jest realistyczna:
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);
}
Używana w ten sposób:
RuleFor(p => p.DateOfBirth)
.Must(BeAValidAge)
.WithMessage("Invalid {PropertyName}");
RuleFor(p => p.DateOfBirth)
.Must(BeAValidAge)
.WithMessage("Invalid {PropertyName}");
To dobry wzorzec do walidacji danych czasowych jak daty czy okna wygaśnięcia.
Ostateczne Przemyślenia i Rekomendacje
Tim kończy, podsumowując kluczowe zalety FluentValidation:
-
Centralna logika walidacji
-
Łatwość tworzenia niestandardowych walidatorów
-
Kompatybilność zarówno z .NET 5 i nowszymi, jak i starszymi środowiskami
-
Obsługa skomplikówanych modeli, list i reguł asynchronicznych
- Idealna dla hobbystów oraz projektów komercyjnych
Zachęca widzów do zbadania dokumentacji FluentValidation w poszukiwaniu zaawansowanych sposobów użycia, w tym zagnieżdżonych reguł, walidacji właściwości email i innych.
Wnioski
FluentValidation umożliwia programistom .NET budowanie silnie typowanych reguł walidacji, które są wielokrotnego użytku, ekspresywne i łatwe w utrzymaniu. Czy rozwijasz się przy użyciu .NET Core, .NET 8, czy też utrzymujesz systemy dziedziczne na .NET Core 3.1, ta biblioteka sprawia, że walidacja danych jest prosta.
Z funkcjami takimi jak:
-
Płynny interfejs do budowania reguł
-
Wsparcie dla niestandardowej logiki walidacji kodów pocztowych
-
Łatwa integracja z Visual Studio
-
Kompatybilność z testowaniem API, WinForms i ASP.NET
- Solidna obsługa awarii walidacji
FluentValidation to must-have w twoim zestawie narzędzi .NET. Więcej szczegółów znajdziesz oglądając pełne wideo i subskrybując Kanał Tima dla więcej wglądowych filmów o C#.
Porada: Jeśli jesteś nowy w używaniu FluentValidation, spróbuj zaimplementować własny CustomerValidator z regułami dla właściwości, takich jak public string Name, string Postcode i więcej. Przetestuj to z pomocą mock API lub formularza UI, aby uzyskać praktyczne doświadczenie.
