FluentValidation
Maqolani boshlashdan avval validatsiya o’zi nima ekanligi haqida bir og’iz:
Validatsiya — bu, ma'lumotlarni saqlash yoki ishlashdan avval, belgilangan qoidalarga va cheklovlarga muvofiqligini tekshirish jarayonidir.
.NET’da ma’lumotlarni to’g’riligini tekshirishning (endi validatsiya deb yuritiladi) bir nechta yo’llari mavjud. Masalan ulardan biri bu Data Annotation (batafsil:). Va yana biri esa qo’shimcha package yordamida validatsiya qilish. Ushbu maqolada Data Annotation usuli bilan emas balki FluentValidation (batafsil) package’i orqali validatsiyani amalga oshirishni ko’rib chiqamiz. Kettik!
Nega Data Annotation emas, Fluent Validation?
Xususiyat | Fluent Validation | Data Annotation |
---|---|---|
Sintaksis & O‘qishga qulayligi | Qiyin logikalar uchun oson, yaxshiroq o‘qiladi | Attribut orqali e’lon qilinadi |
Testga oson/qiyinligi | Unit test’lar uchun oson, chunki validatsiyalar qismi alohida klasslarda bo‘ladi | Test qilish uchun qiyinroq, chunki validatsiya qismlari alohida klassda emas balki Model class’ni o‘zida e’lon qilinadi |
Qayta ishlatish mumkin yoki yo‘q | Beeemalol qayta ishlatsa bo‘ladi ya’ni validatsiya qismlari alohida klassda bo‘lganligi bois ularni turli xil project’lar-aro ishlatsak bo‘ladi | Modelda to‘g‘ridan-to‘g‘ri e’lon qilinganligi sababli, qayta ishlatish murakkabroq |
Xatoliklar haqida xabar berishi | O‘zimiz xohlagancha Error message’lar berishimiz mumkin | Bazaviy (odatiy) error xabarlar. |
FluentValidation — ishni boshlaymiz
Avval o’rnatib olamiz:
dotnet add package FluentValidation
Validatorlar e’lon qilamiz
Bizga AbstractValidator<T>
’dan meros oluvchi bitta class kerak bo’ladi va u class’ni ichiga ma’lumotlar uchun qoidalar/ma’lumotlar yozamiz. AbstractValidator<T>
FluentValidation’dan keladi. Kettik:
using FluentValidation;
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(user => user.Name)
.NotEmpty()
.WithMessage("Ismni kiritish majburiy!");
RuleFor(user => user.Email)
.EmailAddress()
.WithMessage("Iltimos to'g'ri pochta manzilini kiriting!");
RuleFor(user => user.Age)
.InclusiveBetween(18, 60)
.WithMessage("Yoshingiz 18 dan oshgan va 60 dan kichik bo'lishi kerak!");
}
}
Demak AbstractValidator<T>
ni ichiga biz cheklovlar o’rnatmoqchi bo’lgan Model Class’imizni nomini berib yuborar ekanmiz. Metodni ichida RuleFor
kalit so’zi orqali turli-xil cheklovlar qo’ysak bo’ladi. WithMessage()
orqali biz o’zimiz xohlagan error message’larni berib yuborsak bo’ladi. Aslida bermasak ham error message ko’rsatadi lekin o’zinikini ko’rsatadi ya’ni masalan “user.Name mustn’t be null” bo’lishi mumkin.
Ma’lumotni validator orqali tekshirish
Yuqorida ochgan class’imizga instance ochamiz va uni ichida Validate()
degan method bor. Usha bilan ma’lumotimiz biz o’rnatgan qoidalarga tushadimi yo’qmi tekshiramiz:
var user = new User { Name = "", Email = "invalid", Age = 17 };
var validator = new UserValidator();
var result = validator.Validate(user);
if (!result.IsValid)
{
foreach (var error in result.Errors)
{
Console.WriteLine($"{error.PropertyName}: {error.ErrorMessage}");
}
}
Demak Validate()
method’i ichiga biz tekshirmoqchi bo’lgan ma’lumotlarimizni beramiz va uni biz o’rnatgan qoidalarga tushadimi yo’qmi tekshirib javobni result
o’zgaruvchisiga solib qo’yadi. Uni ichida esa isValid
bor va u bool
qaytaradi. Agarda false bo’lsa demak biz o’rnatgan shartlar qanoatlantirilmagan bo’ladi. Tamom, Fluent Validation’ni oddiy ishlatilinishi shu qadar.
Fluent Validation’ni murakkabroq ishlatish
Yuqorida biz oddiy ishlatishni ko’rib chiqdik. U yerda bor narsalardan foydalandik ya’ni masalan:
RuleFor(user => user.Name)
.NotEmpty()
.WithMessage("Ismni kiritish majburiy!");
Masalan bu yerda .NotEmpty()
method’i o’zi bor va u string’ni bo’sh yoki yo’qligini tekshiradi. Lekin bizga murakkabroq tekshirishlar kerak, masalan string’imiz faqatgina katta harflardan tashkil topgan bo’lishi kerak bo’lsachi, nima qilamiz???
Qoidalarga qoida qo’shish
Fluent Validation’ni ichida bor method’lardan tashqari o’zimiz ham qoidalar yozsak bo’ladi, albatta qoida yozish uchun ichidagi method’ni ishlatamiz 😃:
RuleFor(user => user.Password)
.NotEmpty()
.MinimumLength(8)
.Matches(@"[A-Z]").WithMessage("Parol faqatgina katta harflardan iborat bo'lishi shart!");
Bu yerda .Matches
qilsak solishtiradi, agarda Matches shartiga tushmasa albatta bu false
bo’ladi.
RuleFor(user => user.ConfirmPassword)
.Equal(user => user.Password)
.WithMessage("Parollar bir-biriga o'xshashi shart!");
Ma’lum bir ma’lumot boshqa ma’lumotga qaram bo’lishiham mumkin, masalan tasavur qiling yangi parol yozyapsiz va uni ikki martta yozasiz, ikkalasiham bir-biriga o’xshashi shart. Shunda ishlatsak bo’ladi.
Murakkabroq ishlatish — loyiha talabiga qarab o’zgarib ketaveradi. Ko’proq ma’lumot olish uchun albatta FluentValidation’ning rasmiy dokumentatsiyasini o’qib chiqishni qattiq tavsiya qilaman: https://docs.fluentvalidation.net/en/latest/aspnet.html