Asp.Net Core MVC FluentValidation
Bu gönderide bir .net core örnek projesi yapacağız ve bu projede validation işlemlerini kolaylaştıran FluentValidation kütüphanesini kullanacağız.
Intro
Mvc projelerinde validation işlemleri DataAnnotation attributeleri ile sağlanıyor bu yöntem ile modelin okunurluğu düşük oluyor. aşağıdaki gibi bir model hem biraz karışık hem de komplike durumlar için yetersiz kalıyor. Örneğin Name alanı dolu ise username zorunlu olsun gibi bir zorunluluğu yapamayız. Ayrıca ilgili modelimizin tek bir görevi olmalı (ViewModel, entity vs.) validasyon işlemlerini farklı bir obje yapmalı.

Projenin oluşturulması ve Paketlerin yüklenmesi
Visual Studio 2022 ve .net 5.0 seçeneğiyle projeyi oluşturuyoruz. (fluentvalidation .net 6.0 tamamen desteklemiyor 27 kasım 2021 itibariyle)

Nuget üzerinden aşağıdaki paketi kuralım

Models klasörü içine bir student objesi oluşturalım

Validators adında bir klasör açıp içine StudentValidator adında bir class oluşturalım.
1 2 3 4 5 6 7 8 9 |
public class StudentValidator : AbstractValidator<Student> { public StudentValidator() { RuleFor(s => s.Name).NotEmpty().Length(2, 100); RuleFor(s => s.Surname).NotEmpty().Length(2, 100); RuleFor(s => s.Email).EmailAddress(); } } |
Oluşturduğumuz validatoru startupda kaydedelim.
1 2 |
services.AddMvc().AddFluentValidation (fv => fv.RegisterValidatorsFromAssemblyContaining<StudentValidator>()); |
Validatoru kaydetmenin birden çok yolu var services.AddTransient<IValidator<Student, StudentValidator>(); gibi bir yöntemde izlenebilir ama bizim tercihimiz daha hızlı ve daha temiz olduğu için assembly şeklinde oldu. böylece bütün abstractvalidator nesnesini miras alan validatorler otomatik kayıt olacak.
Oluşturduğumuz validator şimdilik basit olacak, daha sonra daha komplike durumlar için düzelteceğiz.
Şimdi StudentController açıp bir Create actionu ve view’ı oluşturalım.
StudentController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class StudentController : Controller { public IActionResult Index() { return View(); } public IActionResult Create() { return View(); } [HttpPost] public IActionResult Create(Student student) { if (!ModelState.IsValid) { return View(student); } return View(); } } |
Student/Create.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@model Student <div asp-validation-summary="ModelOnly"></div> <form asp-action="Create"> Name: <input asp-for="Name" /> <span asp-validation-for="Name"></span> <br /> Surname: <input asp-for="Surname" /> <span asp-validation-for="Surname"></span> <br /> Email: <input asp-for="Email" /> <span asp-validation-for="Email"></span> <br /> <br /><br /> <input type="submit" value="Save" /> </form> |
Çalıştırıp baktığımızda validaton elementleri içine otomatik eklediğini göreceğiz.

Kaydet tıklayıp breakpointle baktığımızda ModelState.IsValid false dönecektir.

Temel düzeyde validasyon işlemlerini yaptık şimdi işleri biraz daha komplike edelim. validatoru aşağıdaki gibi değiştirelim.
StudentValidator.cs
1 2 3 4 5 6 7 8 9 10 |
public class StudentValidator : AbstractValidator<Student> { public StudentValidator() { RuleFor(s => s.Name).NotEmpty().Length(2, 100).WithMessage("İsim alanı en az 2 karakter olmak zorundadır"); RuleFor(s => s.Surname).NotEmpty().Length(2, 100).WithMessage("Soyisim alanı en az 2 karakter olmak zorundadır"); RuleFor(s => s.Email).NotEmpty().EmailAddress().WithMessage("E-posta geçerli bir format değil"); RuleFor(s => s.IdentityNumber).NotEmpty().Length(11).WithMessage("Kimlik Numaranız 11 haneli olmaz zorunda").When(s => s.IsTurkish); } } |
Bu durumda hem mesaj içeriklerini değiştirmiş olduk hem de sadece Türk Öğrenciler için T.C girilmesini zorunlu hale getirdik.
Create.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@model Student <div asp-validation-summary="ModelOnly"></div> <form asp-action="Create"> Name: <input asp-for="Name" /> <span asp-validation-for="Name"></span> <br /> Surname: <input asp-for="Surname" /> <span asp-validation-for="Surname"></span> <br /> Email: <input asp-for="Email" /> <span asp-validation-for="Email"></span> <br /> IsTurkish: <input asp-for="IsTurkish" /> <span asp-validation-for="IsTurkish"></span> <br /> Identity Number: <input asp-for="IdentityNumber" /> <span asp-validation-for="IdentityNumber"></span> <br /> <br /><br /> <input type="submit" value="Save" /> </form> |
Client Validation
Bu doğrulamaların hepsini server kaynaklı yaptık, daha büyük bir modelde her seferinde servera gidip cevap almak biraz maliyetli olabilir bunun önüne geçmek için jqueryvalidate ve jquery.validate.unobtrusive kütüphanelerini kullanacağız. Layout.cshtml’e aşağıdaki iki scripti ekleyelim.
1 2 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.min.js" integrity="sha512-37T7leoNS06R80c8Ulq7cdCDU5MNQBwlYoy1TX/WUsLFC2eYNqtKlV0QjH7r8JpG/S0GUMZwebnVFLPd6SU5yg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.min.js" integrity="sha512-o6XqxgrUsKmchwy9G5VRNWSSxTS4Urr4loO6/0hYdpWmFUfHqGzawGxeQGMDqYzxjY9sbktPbNlkIQJWagVZQg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> |
Şimdi formu kaydettiğimiz zaman servera gitmeyecek fakat jquery validation sadece temel işlemleri sağlıyor notempty, length vs. gibi doğrulamalarda servera gitmeden uyarıyı veriyor, ama when() kullandığımız komplike durum için servera gitmesi gerekli.
Sonuç
FluentValidation kütüphanesi ile validation işlemlerimizi çok daha kolay ve hızlı yapabiliriz. Validation kurallarını bir sürü yöntemle çeşitlendirebilirsiniz. Bu kütüphaneyi sadece mvc değil apilerinizde de kullanabilirsiniz.
Başka bir yazıda görüşmek üzere 🙂