Validation kullanımı

Validation ile formlardan gelen veri kontrolünü yapılabilir ve kullanıcıya gerekli uyarı mesajlarını gösterebiliriz.

Validation yardımıyla sistemimize gönderilecek form verilerini kontrol ederek hatalı alanların geri dönüşünü kullanıcıya yapabiliriz. 

Örnek olarak bir Register formu oluşturalım ve bu form üzerinden girilecek bilgileri bazı kontroller vasıtasıyla kontrol edelim.

Öncelikle register Modelimizi oluşturuyoruz.

BlogProject.Entity içerisinde oluşturduğum Register.cs class içeriği

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace BlogProject.Entity
{
   public class Register
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public string PassWord { get; set; }
        public bool TermsAccepted { get; set; }
        [UIHint("Date")]
        public DateTime? BirtDate { get; set; }
    }
}

Modelin veritabanına kayıt işlemleri için BlogProject.Data.Abstract klasoru içerisine IRegisterRepository.cs interface'ini ve onunla ilişikili EfRegisterRepository.cs tanımadım. Şöyle ki;

IRegisterRepository.cs

using BlogProject.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogProject.Data.Abstract
{
    public interface IRegisterRepository
    {
        void AddUser(Register register);
        Register GetByID(int ID);
        void UpdateUser(Register register);
        void DeleteUser(Register register);
    }
}

 

BlogProject.Data.Concrete.EfCore / EfRegisterRepository.cs , IRegisterRepository.cs interface'inden türediği için Interface de tanımlı modellerle uyumlu olmak durumundadır.

 

using BlogProject.Data.Abstract;
using BlogProject.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BlogProject.Data.Concrete.EfCore
{
    public class EfRegisterRepository : IRegisterRepository
    {
        private BlogContext context;
        public EfRegisterRepository(BlogContext _context)
        {
            context = _context;
        }

        public void AddUser(Register register)
        {
            context.Registers.Add(register);
            context.SaveChanges();
        }

        public void DeleteUser(Register register)
        {
            throw new NotImplementedException();
        }

        public Register GetByID(int ID)
        {
            return context.Registers.FirstOrDefault(p => p.ID == ID);
        }

        public void UpdateUser(Register register)
        {
            var user = GetByID(register.ID);
            user.PassWord = register.PassWord;
            user.Email = register.Email;
            context.SaveChanges();
        }
    }
}

 

BlogContext.cs içerisinde DbSet tanımlamasını yapıyoruz.

 

using BlogProject.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogProject.Data.Concrete.EfCore
{
    public class BlogContext : DbContext
    {
        public BlogContext(DbContextOptions<BlogContext> options)
            : base(options)
        {

        }
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<User> Users { get; set; }
        public DbSet<Viewer360> Viewer360s {get; set;}
        public DbSet<Register> Registers { get; set; }
    }
}

 

Action Register HomeController.cs içerisinde tanımlandığı için HomeController içerisinde IRegisterRepository.cs Interfaceini tanımlıyoruz. Daha önceden IBlogRepository.cs Interface i tanımlanmıştı.

 

private IBlogRepository BlogRepository;
        private IRegisterRepository RegisterRepository;
        public HomeController(IBlogRepository repo, IRegisterRepository register)
        {
            BlogRepository = repo;
            RegisterRepository = register;
        }

 

HomeContoller.cs / Register Action'ın [HttpGet] , [HttpPost] methotları ve Model.isValid olduğunda yönlenecek Completed Action'ı tanımlıyoruz.

        [HttpGet]
        public IActionResult Register()
        {
            return View(new Register() { BirtDate = DateTime.Now });
        }

        [HttpPost]
        public IActionResult Register(Register register)
        {
            if (string.IsNullOrEmpty(register.UserName))
            {
                ModelState.AddModelError(nameof(register.UserName), "User Name zorunludur.");
            }
            if (string.IsNullOrEmpty(register.PassWord))
            {
                ModelState.AddModelError(nameof(register.PassWord), "Şifre alanı zorunludur");
            }
            else if (register.PassWord.Count()<6)
            {
                ModelState.AddModelError(nameof(register.PassWord), "Şifre minimum 6 karakter olmalıdır");
            }
            if (string.IsNullOrEmpty(register.Email))
            {
                ModelState.AddModelError(nameof(register.Email), "Eposta alanı zorunludur");
            }
            else if (!register.Email.Contains("@"))
            {
                ModelState.AddModelError(nameof(register.Email), "Eposta adresiniz Hatalıdır.");
            }
            if (register.TermsAccepted!=true)
            {
                ModelState.AddModelError(nameof(register.TermsAccepted), "Kullanım koşullarını onaylamayan kullanıcıların üyelik taleplerini kabul edemiyoruz.");
            }

            if (string.IsNullOrEmpty(register.BirtDate.ToString()))
            {
                ModelState.AddModelError(nameof(register.BirtDate), "Lütfen doğum tarihinizi giriniz");
            }
            else if (register.BirtDate?.Year>(DateTime.Now.Year-7))
            {
                ModelState.AddModelError(nameof(register.BirtDate), "7 Yaşından küçükler sistemimize üye olamaz");
            }

            if (ModelState.IsValid)
            {
                RegisterRepository.AddUser(register);
                return View("Completed", register);
            }
            else
            {
                return View(register);
            }
            
        }

        [HttpGet]
        public IActionResult Completed()
        {
            return View();
        }

 

Register.cshtml 
 

@model Register
@{
    ViewData["Title"] = "Register";
}
@section scripts{ 
    <script src="~/lib/jquery/dist/jquery.js"></script>
<script>
    $(function () {
            //formda input nesnelerinde input-validation-error 'u aradık.
            $("input.input-validation-error")
            // Yukarıdaki şarta uygun veri bulununca alttaki kodla bulunan kodun bir üst sekmesine geçiş yapıyoruz ilk form-group'a
            //.closest(".form-group")
            // içinde bulunduğumuz form-group içerisinde has-danger (bootstrap css kodu) i ekliyoruz.
            .addClass("alert-danger");
    });
</script>
}
<div class="jumbotron container-fluid text-center bg-dark text-light">
    <h1 class="display-4">Selam Dünyalı!</h1>
    <p class="lead">Burası benim kişisel araştırma kütüphanem, karşılaştığım sorunların çözümlerini burada tutuyorum.</p>
    <p class="lead">Ben öğrenmek istiyorum , ya sen?</p>
    <hr class="my-4 bg-secondary">
    <p>
        “Yaşasın bir daha ölmemek üzere dirilmek!”
        <br />
        Şamil Salmanoviç Basayev.
    </p>
</div>


<div class="container p-3">
    <div class="row">
        <div class="col-md-3">
            @await Component.InvokeAsync("CategoryMenu")
        </div>
        <div class="col-md-9">
            <h1>Register</h1>

            <form asp-action="Register" asp-controller="Home" method="post">
                <div class="text-danger" asp-validation-summary="All">

                </div>
                <div class="form-group">
                    <label asp-for="UserName">User Name</label>
                    <div><span class="text-danger" asp-validation-for="UserName"></span></div>
                    <input asp-for="UserName" class="form-control" />
                </div>
                <div class="form-group">
                    <label asp-for="PassWord">Password</label>
                    <div><span class="text-danger" asp-validation-for="PassWord"></span></div>
                    <input asp-for="PassWord" class="form-control" />
                </div>
                <div class="form-group">
                    <label asp-for="Email">E-Mail</label>
                    <div><span class="text-danger" asp-validation-for="Email"></span></div>
                    <input asp-for="Email" class="form-control" />
                </div>
                <div class="form-group">
                    <label asp-for="BirtDate">Birt Date</label>
                    <div><span class="text-danger" asp-validation-for="BirtDate"></span></div>
                    <input asp-for="BirtDate" asp-format="{0:d}" class="form-control" />
                </div>
                <div class="radio form-group">
                    <input asp-for="TermsAccepted" class="form-check-input" />
                    <div><span class="text-danger" asp-validation-for="TermsAccepted"></span></div>
                    <label asp-for="TermsAccepted">Lütfen hizmet şartlarımızı okuyup onaylayın.</label>
                </div>
                <div class="form-group">
                   <input type="submit" class="btn btn-primary" value="Register" />
                </div>
            </form>
        </div>
    </div>
</div>

 

Completed.cshtml

@model Register
@{
    ViewData["Title"] = "Completed";
}

<div class="jumbotron container-fluid text-center bg-dark text-light">
    <h1 class="display-4">Selam Dünyalı!</h1>
    <p class="lead">Burası benim kişisel araştırma kütüphanem, karşılaştığım sorunların çözümlerini burada tutuyorum.</p>
    <p class="lead">Ben öğrenmek istiyorum , ya sen?</p>
    <hr class="my-4 bg-secondary">
    <p>
        “Yaşasın bir daha ölmemek üzere dirilmek!”
        <br />
        Şamil Salmanoviç Basayev.
    </p>
</div>


<div class="container p-3">
    <div class="row">
        <div class="col-md-3">
            @await Component.InvokeAsync("CategoryMenu")
        </div>
        <div class="col-md-9">
            <h1>Completed</h1>
            <div class="form-group">
                <p>
                    Merhaba @Model.UserName sistemimize üye olduğunuz için teşekkür ederiz.
                    <br />
                    Kullanıcı bilgileriniz @Model.Email Email adresinize gönderilmiştir.
                    <br /> 
                    Şifre : @Model.PassWord
                    <br />
                    Kullanıcı adınız : @Model.UserName or @Model.Email
                    <br />
                    Görüşmek dileğiyle.
                </p>
            </div>
            
        </div>
    </div>
</div>

 

Startup.cs içerisinde IRegisterRepository.cs i tanımlamalıyız.
 

public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IBlogRepository, EfBlogRepository>();
            services.AddTransient<ICategoryRepository, EfCategoryRepository>();
            services.AddTransient<IViews360Repository, EfViews360Repository>();
            services.AddTransient<IRegisterRepository, EfRegisterRepository>();


            services.AddDbContext<BlogContext>(options => options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection"),b=>b.MigrationsAssembly("BlogProject.WebUI")));

            services.AddRazorPages();
        }

 

Modeli oluşturduktan sonra Dotnet ef migrations add Register_ef ile yeni migration tanımlamasını yapmıştım.

Bu sayede proje ilk çalıştırıldığında BlogProject.Data.Concrete.EfCore içerisinde SeedData.cs içerisine yazılmış kod bloğu ile Bekleyen Migration çalıştırılacak ve gerekli veritabanı değişiklikleri yapılacak. Eğer SeedData.cs gibi bir kontrol kodumuz yoksa cmd tarafında update komutunu çalıştırmamız gerekiyor.
 

using BlogProject.Entity;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BlogProject.Data.Concrete.EfCore
{
    public static class SeedData
    {
        public static void Seed(IApplicationBuilder app)
        {
            BlogContext context = app.ApplicationServices.GetRequiredService<BlogContext>();
            context.Database.Migrate();


            if (!context.Users.Any())
            {
                context.Users.AddRange(
                    new User() { UserName = "Admin Kullanıcı", UserMail = "admin@gmail.com", PassWord = "12345", Role = Role.Admin },
                    new User() { UserName = "User Kullanıcı", UserMail = "user@gmail.com", PassWord = "12345", Role = Role.User },
                    new User() { UserName = "Member", UserMail = "member@gmail.com", PassWord = "12345", Role = Role.Member }
                    );
                context.SaveChanges();
            }
        }
    }
}

 

Validation işlemlerimizi Model sınıfı yerine , Controller içerisinde tanımladığımız için Modeli kullanacağımız tüm formlarda Validation kontrolü yazmamız gerekiyor. Validation kontrollerini Model içerisinde tanımlamayı bir sonraki derste işleyeceğiz.

Yukarıda ki kodlar Server tabanlı çalıştığı için her istek sunucu tarafına gider ve şartlara bağlı kontroller yapıldıktan sonra uyumsuzluk varsa hata mesajları geri döner, bu işlem için jquery-validation kütüphanesini kullanarak Client (browser) tarafında da yaptırabiliriz bu sayede hem sunucuyu meşgul etmeyiz hem de sayfa yenilenip tekrar açılmaz böylece daha hızlı çalışır.

Bir sonraki derste, hem model üzerinde [Required] tanımlamayı hem de javascript kütüphanelerinin sisteme dahil edilmesini işleyeceğiz.