Makale Özeti

Enterprise Library 3.0 ile birlikte gelen Validation Application Block yapısını inceliyoruz. Attribute kullanarak kısa yoldan property uzunluğu, verinin şekli, alacağı maximum veya minimum değerleri çok kolay bir şekilde nasıl kontrol edebileceğimiz anlatılmaktadır.

Makale

Yazılan uygulamalardaki veri girişlerini sürekli kontrol ederiz. Genelde güvenlik üzerine olan bu veri giriş kontrolü, uygulamanın sağlıklı çalışması açısından da son derece önemlidir. .Net Framework altyapısında validator’lar, Regex … gibi farklı yapılar sayesinde girdi kontrolü mevcuttur. Bu yapılara bir yenisi daha eklendi. Validation Application Block adı verilen bu altyapı Enterprise Library 3.0 ile karşımıza çıkıyor. Attribute kullanarak kısa yoldan property uzunluğu, verinin şekli, alacağı maximum veya minimum değerleri çok kolay bir şekilde kontrol edebiliyoruz.

Validation Application Block  ile çalışabilmeniz için öncellikte download etmeniz gerekiyor.

Download için : http://www.codeplex.com/entlib

Download için : http://www.microsoft.com/downloads/details.aspx?familyid=62ef5f79-daf2-43af-9897-d926f03b9e60&displaylang=en

 

Burada akla şu soru geliyor. Ben bunları zaten Web uygulamalarında Validation’lar sayesinde, Windows uygulamaları tarafında Regex ile yapıyorum bana Validation Application Block’un getirdiği yenilik nedir?

Validation Application Block ile sınıflar üzerinde yapılan kontroller sayesinde web ya da Windows arayüzleri için bir daha kontrol mekanizması yapmak zorunda kalmıyoruz. Kontrolü bir kere yapıyoruz, web ve windows uygulamaları için kontrol otomatik olarak yapılmış oluyor.

Not : Bu makale Enterprise Library 3.0 ile birlikte gelen Validation Application Block mekanizmasını anlatmaktadır. Validation Framework ile karıştırılmamalıdır.

İncelemeye örnek üzerinden başlayalım. Aşağıdaki gibi bir sınıfımız olsun:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace Katmanim

{

    public class Personel

    {

        private string _Ad;

        private string _Soyad;

        private string _Email;

        private int _Yas;

        public string Ad

        {

            get { return _Ad; }

            set { _Ad = value; }

        }

        public string Soyad

        {

            get { return _Soyad; }

            set { _Soyad = value; }

        }

        public string Email

        {

            get { return _Email; }

            set { _Email = value; }

        } 

        public int Yas

        {

            get { return _Yas; }

            set { _Yas = value; }

        }

 

    }

}

Bu sınıf üzerindeki Property’lerimizde validation mekanizmasını kullanacağız. Sözde katman görevi görecek bu projeye Enterprise Library ile birlikte gelen Microsoft.Practices.EnterpriseLibrary.Validation dll’ini referans olarak ekliyoruz. Yazdığımız sınıfa göre yapmamız gereken kontrol mekanizmasını listeleyecek bir senaryo uyduralım;

  1. Ad ve Soyad uzunlukları 3 ile 20 arasında olsun.
  2. Email doğru formatta girilsin.
  3. Yas 1 ile 100 arasında olsun.
  4. Bütun Property’ler boş geçilemesin.

İhtiyaçlarımızı belirledikten sonra artık gerekli kontrolleri yapmaya başlıyoruz. Ad ve Soyad için gerekli olmalı, uzunluk aralığı 3 ile 20 arasında olmalı dendiği için Property’de kullanmamız gereken ilk attribute StringLengthValidator. Bu attribute sayesinde bir property’nin alacağı minimum ve maximum uzunluğu belirleyebiliyoruz. Ek olarak kuralımıza uyulmadığı taktirde vereceği hatayı belirtiyoruz. Ek olarak boş geçilmesi istenmediği için NotNullValidator attribute’ü kullanıyoruz.

[StringLengthValidator(3, 20, Ruleset="RuleSetA" , MessageTemplate="Ad 3 ile 30 karakter arasında olmalı")]

        [NotNullValidator(MessageTemplate="Boş Geçilemez")]

        public string Ad

        {

            get { return _Ad; }

            set { _Ad = value; }

        }

Burada RuleSetA olarak belirtilen ise sadece bir gruplamadır. Farklı gruplar için farklı kontrol mekanizması sağlayabiliyoruz. Ad ve Soyad için kontrol aynı olduğu için Soyad property’sini de aynı şekilde kontrol ediyoruz.  

[StringLengthValidator(3, 20,Ruleset="RuleSetA" , MessageTemplate = "Soyad 3 ile 30 karakter arasında olmalı")]

        [NotNullValidator(MessageTemplate="Boş Geçilemez")]

        public string Soyad

        {

            get { return _Soyad; }

            set { _Soyad = value; }

        }

Bizden 3. olarak istenen ise Email property’sine düzgün formatta giriş yapılsın ve boş geçilemesin. Bunun için regex yazmamız gerekecek. Email , internet sitesi adresi veya herhangi özel bir formatı olanlar için bildiğiniz gibi regex yazılıyor. Validation Application Block içerisinde Regex yazacağımız attribute ise RegexValidator attribute’dür. Kontrol edilmiş Email property’sinin yeni hali aşağıdaki gibidir.

   [RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", MessageTemplate = "Geçersiz Email", Ruleset = "RuleSetA")]

  [NotNullValidator(MessageTemplate="Boş Geçilemez")]

        public string Email

        {

            get { return _Email; }

            set { _Email = value; }

        }

 4. olarak istenen ise Yaş kontrolüdür. 1 ile 100 arasında veri girişine izin verilecek olan bu property için kullanacağımız attribute RangeValidator attribute’dür. Bu attribute kullanımı için 8 overload mevcut , biz örneğimizde 2. overload’u kullanacağız. Bu overload bizden 5 parametre olacak. Bunlar :

  • Alt Değer
  • Alt değer için aynı girilen değere vereceği tepki
  • Üst Değer
  • Üst değer için aynı girilen değere vereceği tepki
  • Parametreler (MessageTemplate, RuleSet.. gibi bilgiler)

[RangeValidator(1 ,RangeBoundaryType.Inclusive, 100, RangeBoundaryType.Exclusive, MessageTemplate="Yaş 1 ile 100 arasında olmalı", Ruleset="RuleSetA")]

        [NotNullValidator(MessageTemplate="Boş Geçilemez")]    

        public int Yas

        {

            get { return _Yas; }

            set { _Yas = value; }

        }

Burada RangeBoundaryType.Inclusive olarak belirlenen alt veya üst limit ile aynı değere izin verileceğidir. Örneğin yukarıdaki property’e göre 1 ve 100 sayılarına izin verilmektedir. RangeBoundaryType.Exclusive yaparak 1 ve 100 hariç bir aralık tanımlaması yapabilirsiniz.

Standart olarak 4 Property kontrolü yapılan bir sınıf yazdık. Sınıfımızın tam hali aşağıdaki gibidir:

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

using Microsoft.Practices.EnterpriseLibrary;

using Microsoft.Practices.EnterpriseLibrary.Validation;

 

namespace Katmanim

{

    public class Personel

    {

        private string _Ad;

        private string _Soyad;

        private string _Email;

        private int _Yas;

        [StringLengthValidator(3, 20, Ruleset="RuleSetA" , MessageTemplate="Ad 3 ile 30 karakter arasında olmalı")]

        [NotNullValidator(MessageTemplate = "Ad Boş Geçilemez", Ruleset = "RuleSetA")]

        public string Ad

        {

            get { return _Ad; }

            set { _Ad = value; }

        }

        [StringLengthValidator(3, 20,Ruleset="RuleSetA" , MessageTemplate = "Soyad 3 ile 30 karakter arasında olmalı")]

        [NotNullValidator(MessageTemplate = "Soyad Boş Geçilemez", Ruleset = "RuleSetA")]

        public string Soyad

        {

            get { return _Soyad; }

            set { _Soyad = value; }

        }

        [RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", MessageTemplate = "Geçersiz Email", Ruleset = "RuleSetA")]

        [NotNullValidator(MessageTemplate = "Email Boş Geçilemez", Ruleset = "RuleSetA")]

        public string Email

        {

            get { return _Email; }

            set { _Email = value; }

        }  

        [RangeValidator(1 ,RangeBoundaryType.Inclusive, 100, RangeBoundaryType.Exclusive, MessageTemplate="Yaş 1 ile 100 arasında olmalı", Ruleset="RuleSetA")]

        [NotNullValidator(MessageTemplate="Boş Geçilemez")]    

        public int Yas

        {

            get { return _Yas; }

            set { _Yas = value; }

        }

 

    }

}

 

Buraya kadar hazırladığımız kontrol mekanizmalarını örnek bir Windows uygulamasında kullanalım. Aşağıdaki gibi basit bir arayüz yapıyorum:

Uygulamamıza referans olarak eklememiz gerekenler :

Katmanim, Microsoft.Practices.EnterpriseLibrary.Common ve Microsoft.Practices.EnterpriseLibrary.Validation dll’leridir. Bunları ekledikten sonra Kaydet butonumuz için gereken kodu yazalım.

// Yeni bir personel tanımla

            Personel p = new Personel();

            p.Ad = txtAd.Text;

            p.Soyad = txtSoyad.Text;

            // Yaş sayısal mı değil mi kontrolü yapıyoruz. Validation Application Block bu kontrolü yapmıyor.

            int yas;

            bool durum = Int32.TryParse(txtYas.Text, out yas);

            if (durum)

            {

                p.Yas = yas;

            }

            else

            {

                MessageBox.Show("Yaş Sayısal Olmalı.\r\nValidation Application Block veri tipi kontrolü yapmadığı için bunu kullandık.",

                    this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return ;

            }

 

            p.Email = txtEmail.Text;

              /* Burada artık kontrol işlemi başlıyor.

             * Kontrol işlemini yapacak olan Generic yapıda olan Validator sınıfıdır.

             *  ValidatorFactory sınıfının CreateValidator sınıfı ise belirtilen sınıftaki Validation

             * kontrolü yapmaktadır. Parametre göndermeden de kullanabilirsiniz ama eğer RuleSet

             * kullandıysanız parametre olarak hangi ruleset kontrolü yapılacağını belirtmemiz gerekiyor

             */

             Validator<Personel> kontrolcu = ValidationFactory.CreateValidator<Personel>("RuleSetA") ;    

            // Dönen sonuçlar ValidationResults cinsinden dönüyor.

            ValidationResults sonuclar = kontrolcu.Validate(p);

             // Gelen sonuçları da ekrana yazdıralım.

            treeSonuclar.Nodes.Clear();

            foreach (ValidationResult result in sonuclar)

            {

                TreeNode node = new TreeNode(result.Message);

                node.Nodes.Add(String.Format("Key = \"{0}\"", result.Key.ToString()));

                node.Nodes.Add(String.Format("Target = <{0}>", result.Target.ToString()));

                node.Nodes.Add(String.Format("Validator = <{0}>", result.Validator.ToString()));

                treeSonuclar.Nodes.Add(node);

            }

Kontrol yapıldıktan sonra aşağıdaki gibi çıktı olmaktadır.

Sonuçlardan karşımıza çıkan bir nokta var. Kullanılan her validator boş gelen veriye tepki veriyor. Örneğin web uygulamalarında CompareValidator kullanıldığı zaman Required olarak belirleyemiyoruz , bir validator daha kullanmamız gerekiyor ama buradaki yapı sonucu fazladan bir de boş geçilemesin kontrolü yapmamıza gerek yok. Biz NotNullValidator kullandık , ama yaptığımız yapıda gereksiz kaldı, asıl kullanım yeri fazladan bir validator kullanmadığımız zaman kullanmaktır. Örneğin:

[NotNullValidator(MessageTemplate = "Soyad Boş Geçilemez", Ruleset = "RuleSetA")]

        public string Soyad

        {

            get { return _Soyad; }

            set { _Soyad = value; }

        }

gibi.

ValidatorAttribute sınıfını inherit ederek kendi özel validatorAttribute’lerinizi yazabilmeniz mümkündür.

Bir sonraki makalede Validation Framework’u inceliyor olacağız.

 

İyi Çalışmalar

Okan Tekeli

C# MVP , MCT