Asp .Net Core FluentValidation

Merhaba arkadaşlar, bugün sizlerle beraber .Net Core bir uygulamada FluentValidation kullanımından bahsederek ufak örneklerle pekiştirmeye çalışacağız. Öncelikle FluentValidation nedir ve neden kullanırız kısaca bundan bahsetmek istiyorum.

Öncelikle FluentValidation’ın asıl amacı datanın doğru olduğunu (model yapısına göre valid mi?) Jquery Validation gibi client-side da kontrol etmek yerine istenirse hem server-side hem client-side (Bunun için yine Jquery validaitondan yardım alır) kontrol edilmesini sağlamaktır. Yani kısaca FluentValidation bir data validaiton kütüphanesidir. Hem client-side validaiton hem backend validaitonın beraber kullanımı veri doğruluğunu garanti etmek adına daha güvenli bir yaklaşımdır.
FluentValidation bu amacıyla beraber, validation kurallarını daha esnek, daha kolay, anlaşılır yazmak ve komplex kuralları belirtmek konusunda diğer alternatif validation kütüphanelerinin önündedir.  Bu arada FluentValidation,  data annocationslarla beraberde kullanılabilir. Fluent validaiton open-source bir projedir. Github reposunu buradan inceleyebilirsiniz.
unsplash-Erwan-Hesry
Ufak bir örnekle FluentValidation kullanımını pekiştirelim. Örnek için .net Core 3 Api projesi açtım. Get ve post işlemimiz olacak. Parametre olarak aldığımız player modelde validation kontrolü yaparak, eğer hata yoksa listemize ekleyeceğiz. Aynı şekilde listeye bilerek eklediğimiz validaitona uymayan bir itemıda get isteğinde göndermemeye çalışacağız.

FluentValidationExample

Öncelikle projemize

Install-Package FluentValidation.AspNetCore
paketini ekleyelim. Configure Servis içerisinde AddControllers().AddFluentValidation()  yada AddMvc().AddFluentValidation() adımına ekleyelim. Burada isterseniz gerekli optionları verebilirsiniz. Biz assemblyde validatorlerimizi taramızı için aşağıdaki şekilde kullanacağız.
 services.AddControllers().AddFluentValidation(fv =>
            {
                fv.RegisterValidatorsFromAssemblyContaining<Startup>();
            });
Sıra geldi validator sınıfımızı yazmaya.
public class PlayerValidator : AbstractValidator<Player>
    {
        public PlayerValidator()
        {
            //RuleSet("test", () =>
            //{
            //    RuleFor(x => x.Name).NotNull().Length(1, 10).WithMessage("name could not be null");
            //    RuleFor(x => x.IsOutOfStaff).NotEqual(true).WithMessage("This player out of staff");
            //});            
            RuleFor(x => x.Name).NotNull().Length(1, 10).WithMessage("name could not be null");
            RuleFor(x => x.TeamName).MinimumLength(3).MaximumLength(50).WithMessage("Team name character length is invalid");
            RuleFor(x => x.IsOutOfStaff).NotEqual(true).WithMessage("This player out of staff");
        }
    }
Burada ruleset ile model için farklı kurallar belirleyebilirsiniz. Bu şekilde kullanımı commentli olarak paylaştım. Biz tek kural seti üzerinden gideceğimiz için bu yapıyı kullanmadık. Daha sonra constructor injection kullanacağımız için Validator sınıfımızı ve servisimizi inject ediyoruz.
services.AddSingleton<IValidator<Player>, PlayerValidator>();
services.AddSingleton<IPlayerService, PlayerService>();
İnjectionu ve paketimizin kurulumunu gerçekleştirdikten sonra _playerValidator.Validate ile validasyonu sağlayailiriz. Farklı ruleset kullanımı için commentli olarak örneği ekledim.
public class PlayerService : IPlayerService
    {
        private readonly IValidator<Player> _playerValidator;
        public PlayerService(IValidator<Player> playerValidator)
        {
            _playerValidator = playerValidator;
        }
        public List<Player> Players = new List<Player>
        {
            new Player{
                Name="Ronaldo",
                TeamName="Juventus",
                IsCanPlay=true
            },
            new Player{
                Name="Messi",
                TeamName="Barcelona",
                IsCanPlay=true
            },
            new Player{
                Name="Mbappe",
                TeamName="PSG",
                IsCanPlay=true
            },
            new Player{
                Name="Neymar",
                TeamName="PSG",
                IsCanPlay=true
            },
            new Player{
                Name="Bale",
                TeamName="Real Madrid",
                IsCanPlay=false
            }
        };

        public string AddPlayer(Player player)
        {
            //var validateResult = _playerValidator.Validate(player, ruleSet: "test");
            var validateResult = _playerValidator.Validate(player);
            if (validateResult.IsValid)
                Players.Add(player);
            return validateResult.IsValid ? "Success" : validateResult.Errors.FirstOrDefault().ErrorMessage;
        }

        public IEnumerable<Player> GetPlayers()
        {
            var resultPlayers = new List<Player>();
            foreach (var player in Players)
            {
                var validateResult = _playerValidator.Validate(player);
                if (validateResult.IsValid)
                    resultPlayers.Add(player);
            }
            return resultPlayers;
        }
    }
Şimdi apimizi Postman aracılığıyla test edelim.

Post

Post metodumuza bir başarılı bir başarısız request atalım.
player Api Post Success
player Api Post Error

Get

player Api Get
Gördüğünüz gibi validasyonumuza uymayan
       new Player{
                Name="Bale",
                TeamName="Real Madrid",
                IsCanPlay=false
            }

kaydını listelemedik.

.Net Core 3 ile modelimizi gönderirken ve alırken validationımızı uygulamış olduk. Umarım faydalı olmuştur.

Kaynaklar
https://docs.fluentvalidation.net/en/latest/aspnet.html
https://www.c-sharpcorner.com/article/using-fluentvalidation-in-asp-net-core/
https://www.bilgeadam.com/blog/yazi/fluent-validation

Written By

Bir önceki günden daha iyi olmak için çalışarak kendimi geliştirmek, öğrendiklerim ve öğreneceklerim ile yazılım sektöründe büyük ölçekli ve uluslararası projelerde kendimden söz ettirmek istiyorum.

More From Author

You May Also Like

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir