W dzisiejszym poście pokażę jak zintegrować _FluentValidation _z ASP.NET MVC5, na podstawie dodawania użytkownika.
Po za standardowym FluentValidation potrzebujemy również FluentValidation.MVC5. Ta biblioteka zapewnia ModelValidatorProvider odpowiedni dla FluentValidation.
Install-Package FluentValidation
Install-Package FluentValidation.MVC5
Następnie w miejscu startu aplikacji (u mnie jest to Application_Start Global.asax) dodajemy taki fragment kodu:
FluentValidationModelValidatorProvider.Configure();
Sprawia on, że od tej pory nasz framework webowy nie będzie korzystał w wbudowanej walidacji przez _DataAnnotations, _tylko z FluentValidation.
Teraz utwórzmy model klasy walidowanej:
[Validator(typeof(UserViewModelValidator))]
public class UserViewModel
{
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Widzimy, że w porównaniu do modelu z poprzedniego posta, różni się on atrybutem Validator. Ten atrybut mówi ASP.NET, że gdy będzie chciał zwalidować obiekt tej klasy, to powinien użyć do tego walidatora z atrybutu.
Walidator:
public class UserViewModelValidator :AbstractValidator<UserViewModel>
{
public UserViewModelValidator()
{
this.RuleFor(r => r.UserName).NotEmpty().Length(0, 50);
this.RuleFor(r => r.Email).NotEmpty().EmailAddress().Length(0, 100);
this.RuleFor(r => r.Password).NotEmpty().Length(6, 50);
}
}
W HomeController dodajemy prosty kod mający symulować dodawanie użytkownika do bazy danych. Gdy dane nie przejdą walidacji to zwracamy widok wraz z tymi danymi. W przeciwnym wypadku przekierowujemy na stronę UserCreated.
[HttpPost]
public ActionResult CreateUser(UserViewModel user)
{
if (!ModelState.IsValid)
return View(user);
// add user to database
return View("UserCreated");
}
Został tylko formularz dodawania użytkowników w HTML. Pod każdym polem formularz używamy ValidationMessageFor, aby pokazać błędy walidacyjne, jakie zwróci kontroler.
<h4>Create a new user.</h4>
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
@Html.ValidationMessageFor(m => m.UserName, string.Empty, new { @class = "text-danger" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
@Html.ValidationMessageFor(m => m.Email, string.Empty, new { @class = "text-danger" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
@Html.ValidationMessageFor(m => m.Password, string.Empty, new { @class = "text-danger" })
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Create" />
</div>
</div>
Po uruchomieniu naszej aplikacji i wpisaniu błędnych danych pojawia się taki o to widok:
Czyli nasza walidacja działa i nieprawidłowe dane zostały zwrócone do użytkownika w celu ich poprawienia.
Walidacja wewnętrznych klas
Integracja pomiędzy _ASP.NET _i _FluentValidation _pozwala na bardzo prostą walidację klas, które są polami naszej głównej klasy. Powiedzmy, że do naszego użytkownika dodajemy pole odpowiedzialne za składowanie informacji o jego adresie. Aby zwalidować taki zagłebiony obiekt należy jedynie powtórzyć powyższe kroki dla klasy adresu. Framework przejdzie po wszystkich polach obiektu walidowanego i jeśli to pole jest połączone z walidatorem, to użyje go by zwalidować ten obiekt. Całość przedstawia się tak:
Model użytkownika rozszerzony o pole adresu:
[Validator(typeof(UserViewModelValidator))]
public class UserViewModel
{
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public AddressViewModel Address { get; set; }
}
Model adresu i jego walidator.
[Validator(typeof(AddressViewModelValidator))]
public class AddressViewModel
{
public string City { get; set; }
public string PostalCode { get; set; }
}
public class AddressViewModelValidator : AbstractValidator<AddressViewModel>
{
public AddressViewModelValidator()
{
this.RuleFor(r => r.City).NotEmpty().Length(1, 50);
this.RuleFor(r => r.PostalCode).NotEmpty().Matches("^[0-9]{2}-[0-9]{3}$");
}
}
I rezultat:
Podsumowanie
Biblioteka FluentValidation w prosty sposób łączy się z ASP.NET MVC, przez co już w kilka chwil możemy korzystać z niej w naszej aplikacji webowej. Dodawanie kolejnych walidatorów jest szybkie i nie wpływa na zmianę dotychczasowej logiki przetwarzania żądań w MVC. Wszystko dzieje się pod spodem, a my tylko korzystamy z dobrodziejstw FluentValidation.
Standardowo, wszystkie pokazane tutaj przykłady są na GitHubie.
Comments:
FluentValidation – integracja z ASP.NET MVC – RadBlog
Dziękujemy za dodanie artykułu - Trackback z dotnetomaniak.pl
FluentValidation – integracja z ASP.NET Web API | RadBlog -
[…] poprzednim poście z cyklu FluentValidation pokazałem jak dodać FluentValidation do ASP.NET MVC. W takim razie […]
Wszystkie trzy artykuły o fluent validation napisane niezwykle przystępnie. Wielkie dzieki za inspirację. Mam nadzieję, że jutro sam potestuję :)
Jakbyś miał z czymś problemy to daj znać na maila to bym o tym posta napisał. Aktualnie mam w planach jeszcze opis DI, lokalizację komunikatów i warunkową walidację.