Tworzenie pierwszego walidatora w FluentValidation

Witaj ponownie w cyklu "Przybornik Juniora"! Po wstępie do FluentValidation, w którym omówiłem, jak ta biblioteka może zrewolucjonizować walidację danych w C#, nadszedł czas, aby wkroczyć na kolejny poziom. Dzisiaj skupimy się na praktycznym aspekcie tej podróży – Tworzeniu pierwszego walidatora.

Walidacja prostych typów danych

Wyobraźmy sobie klasę User, która będzie bazą do walidacji:

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
    public int Age { get; set; }
}

Klasa User jest prosta, ale odzwierciedla typowe wymagania w aplikacjach biznesowych. Naszym zadaniem jest teraz zapewnienie, by dane wprowadzane do tego modelu były prawidłowe.

Przechodząc do tworzenia walidatora, tworzymy klasę UserValidator, która dziedziczy po AbstractValidator<User> z FluentValidation:

using FluentValidation;

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name)
            .NotEmpty().WithMessage("Name is required.");

        RuleFor(user => user.Email)
            .NotEmpty().WithMessage("Email is required.")
            .EmailAddress().WithMessage("Invalid email format.");

        RuleFor(user => user.Age)
            .InclusiveBetween(18, 99)
            .WithMessage("Age must be between 18 and 99.");
    }
}

W UserValidator definiujemy reguły, które sprawdzają, czy Name i Email nie są puste, oraz czy Email ma odpowiedni format. Dodatkowo ustawiamy regułę dla Age, aby wartość ta mieściła się w określonym zakresie. Metoda WithMessage służy do definiowania niestandardowych komunikatów błędów, które są wyświetlane, gdy dane wejściowe nie spełniają określonych kryteriów walidacji, co pozwala na bardziej precyzyjną informację zwrotną dla użytkownika.

Po zdefiniowaniu walidatora możemy go użyć do sprawdzenia, czy obiekt User spełnia nasze kryteria:

var user = new User { Name = "John", Email = "john@example.com", Age = 25 };
var validator = new UserValidator();
var results = validator.Validate(user);

if (!results.IsValid)
{
    foreach (var failure in results.Errors)
    {
        Console.WriteLine($"Property {failure.PropertyName} failed validation. Error was: {failure.ErrorMessage}");
    }
}

W tym przykładzie, jeśli użytkownik John nie spełnia wymagań walidacji, program zwróci informacje o błędach. Dzięki temu możemy łatwo zidentyfikować i poprawić problemy z danymi wejściowymi.

Kiedy wywołujemy validator.Validate(user) na naszym obiekcie user, FluentValidation przeprowadza serię sprawdzeń zgodnie z regułami zdefiniowanymi w klasie UserValidator. Wynikiem tej operacji jest obiekt ValidationResult, który zawiera informacje o wyniku walidacji.

Kluczowe elementy tego wyniku to:

  • IsValid: Jest to właściwość typu bool, która wskazuje, czy obiekt przeszedł wszystkie reguły walidacji bez błędów. Jeśli wszystkie reguły są spełnione, IsValid będzie miało wartość true. W przeciwnym razie, gdy jakakolwiek reguła nie zostanie spełniona, IsValid będzie false.

  • Errors: Jest to kolekcja zawierająca szczegóły błędów walidacji. Każdy element w tej kolekcji jest obiektem ValidationFailure, który dostarcza informacji takich jak PropertyName (nazwa właściwości, która nie przeszła walidacji), ErrorMessage (wiadomość o błędzie) i ewentualnie inne szczegóły związane z błędem.

W naszym kodzie sprawdzamy, czy wynik walidacji (results) jest nieprawidłowy (!results.IsValid). Jeśli tak jest, iterujemy przez kolekcję results.Errors, wypisując informacje o każdym błędzie. To pozwala nam zrozumieć, które elementy danych nie spełniają określonych kryteriów i wymagają korekty.

Dzięki tej metodologii FluentValidation umożliwia nam nie tylko zapewnienie poprawności danych, ale również oferuje jasne i precyzyjne informacje zwrotne, które mogą być wykorzystane do poinformowania użytkownika o potrzebie poprawy wprowadzonych danych.

Podsumowując, w tym poście przedstawiłem podstawy tworzenia pierwszego walidatora w FluentValidation. Rozpoczynając od definicji klasy modelu User, pokazałem, jak skonstruować walidator UserValidator, wykorzystując typowe reguły walidacji takie jak NotEmpty, EmailAddress i InclusiveBetween. Następnie zilustrowałem, jak wykorzystać metodę Validate do oceny poprawności danych, podkreślając znaczenie właściwości IsValid i szczegółów błędów zawartych w Errors. Ten podrozdział służy jako solidna podstawa do zrozumienia i zastosowania walidacji danych w aplikacjach .NET za pomocą FluentValidation.

W następnych postach przyjrzymy się walidatorom udostępnionym przez bibliotekę FluentValidation.

Do zobaczenia w kolejnych postach!