Makale Özeti

“System.ComponentModel.DataAnnotations” isim uzayı NET 3.5 SP1 ile gelen Asp.Net Dynamic Data projesi ile hayatımıza girdi. Hayatımıza girdiği andan itibaren geliştirilen tüm platformlar bu isim uzayına duyarlı geliştirildi. Asp.Net Dynamic Data, Wcf Ria, Silverlight ve şimdide MVC 3 bu isim uzayı ile entegre calışmaktadır. Peki veri açıklması/Data Annotations isim uzayı nedir nasıl kullanılır?

Makale

“System.ComponentModel.DataAnnotations” isim uzayı NET 3.5 SP1 ile gelen Asp.Net Dynamic Data projesi ile hayatımıza girdi. Hayatımıza girdiği andan itibaren geliştirilen tüm platformlar bu isim uzayına duyarlı geliştirildi. Asp.Net Dynamic Data, Wcf Ria, Silverlight ve şimdide MVC 3 bu isim uzayı ile entegre calışmaktadır. Peki veri açıklması/Data Annotations isim uzayı nedir nasıl kullanılır?

Veri Modelini Açıklama

“System.ComponentModel.DataAnnotations” isim uzayı [Required] [Display] gibi semantik nitelikleri kullanarak UI üzerinde kullanılabilecek veri açıklamaları sunmaktadır. DataAnnotations isim uzayı ile birlikte sunulan çözüm veri modeli açıklamaları ile her uygulamada yapılan doğrulama, lokalizasyon gibi ön yüz işlemlerinin otomatik hale getirilmesidir.

Nasıl Çalışır ?

ASP.Net web form, Silverlight (wcf ria) ve Mvc platformları DataAnnotations isim uzayını desteklemektedir. Ben örneklemek için MVC 3 ve Entity Framework Code First uygulaması kullanacağım. Burada anlatılan Entity Framework Code First adress defteri uygulamamıza veri modeli açıklamaları ekleyerek nasıl çalıştığını inceliyelim.

Aşağıda adres defteri uygulaması için gerekli veri modeli bulunmaktadır.

 public  partial  class  Person 
 {
     public int  PersonId  { get ; set ; }
     public string  FullName  { get ; set ; }
     public string  Company  { get ; set ; }
     public DateTime  BirthDay  { get ; set ; }
     public virtual List<Adress>Adresses{ get; set;}
 }

Yapmak istediğimiz kişi verisi girilirken Name değeri boş bırakılmasın veya yirmi karakterden uzun değerler girilmesin. MVC uygulamamızda bu istediğimizi aşağıdaki şekilde yapabiliriz.

 [HttpPost ]
 public  ActionResult  Create (Person  person)
 {
     if (string .IsNullOrEmpty (person.FullName ) )
         ModelState.AddModelError("FullName","Ad değeri boş bırakılamaz" );
     if  (person.FullName  != null  && person.FullName .Length  > 20)
         ModelState.AddModelError("FullName","20 karakterden uzun ad girilemez");
     if  (ModelState .IsValid )
     {
         var  adressBook = new  AdressBook ();
         adressBook.Persons .Add (person);
         adressBook.SaveChanges ();
         return  RedirectToAction ("Index" );
     }
     return  View (person);
 }

Bu kod bloğunda girilen verinin veri yapımıza uygunluğunu test ettik. Fakat sadece bir tek property için bile bir çok if yazmak zorundayız. Karmaşık veri yapalarındaki doğrulama işlemi ciddi bir sorun oluşturacaktır. Bir diğer doğrulama seceneğimizde veri modeli açıklaması oluşturmaktır.

 [MetadataType (typeof (PersonMetadata ))]
 public  partial  class  Person 
 {
 public  class  PersonMetadata 
 {
     [Key , 
     Display (AutoGenerateField  = false )]
     public  int  PersonId  { get ; set ; }
     [Required (ErrorMessage  = "Ad değeri boş bırakılamaz" ),
     Display (Name  = "Ad" ),
     StringLength (20,ErrorMessage  = "20 karakterden uzun ad girilemez" )]
     public  string  FullName  { get ; set ; }
     [Display (Name  = "Şirket" ),
     StringLength(20,ErrorMessage="20 karakterden uzun şirket ismi girilemez")]
     public  string  Company  { get ; set ; }
     [Display (Name  = "Doğum Tarihi" ), 
     Required (ErrorMessage  = "Doğum tarihi boş bırakılamaz" ),
     DataType (DataType . Date  )]
     public  DateTime  BirthDay  { get ; set ; }
 }
 }

Kişileri saklayan bu sınıfa veri modeli açıklamaları ekledik. Doğrudan sınıflarda bulunan public property’lerede açıklama niteliği ekleyebilirsiniz. Ben daha okunabilir olması için Metadata sınıfı ile birlikte veri modeli açıklama niteliklerini kullandım.Yukardaki kod bloğunda Name özelliğinin ekranda “Ad” olarak görüleceğini değerinin boş bırakılamıyacağını ve yirmi karakterden uzun veri girilemeyeceğiniz söylemektedir. Veri doğrulamalasını belirtilen açıklamalara göre MVC bizim için yapacağından Create metodumuz aşağıdaki şekilde olacaktır.

 [HttpPost ]
 public  ActionResult  Create (Person  person)
 {
     if  (ModelState .IsValid )
     {
         var  adressBook = new  AdressBook ();
         adressBook.Persons .Add (person);
         adressBook.SaveChanges ();
         return  RedirectToAction ("Index" );
     }
     return  View (person);
 }

Yukarıda ki kod bloğunda hiç bir veri doğrulaması yapılmıyor. Çünkü ModelBinder sınıfı verdiğimiz veri açıklama nitelikleri ile veri doğrulamasını yapmakta ve sonuçları ModelState verisine yüklemektedir. Sunucu tarafında yapılan kontroller gibi MVC istemci taraftada veriyi doğrulamaktadır. Şimdi MVC projemizde kişi ekleme sayfası oluşturalım.

  @   using  (Html.BeginForm()) {
  @  Html.ValidationSummary(true )
 <fieldset> 
     <legend> Person</legend> 
     <div  class="editor-label"> 
          @  Html.LabelFor(model => model.FullName)
     </div> 
     <div  class="editor-field"> 
          @  Html.EditorFor(model => model.FullName)
          @  Html.ValidationMessageFor(model => model.FullName)
     </div> 
     <div  class="editor-label"> 
          @  Html.LabelFor(model => model.Company)
     </div> 
     <div  class="editor-field"> 
          @  Html.EditorFor(model => model.Company)
          @  Html.ValidationMessageFor(model => model.Company)
     </div> 
     <div  class="editor-label"> 
          @  Html.LabelFor(model => model.BirthDay)
     </div> 
     <div  class="editor-field"> 
          @  Html.EditorFor(model => model.BirthDay)
          @  Html.ValidationMessageFor(model => model.BirthDay)
     </div> 
     <p> 
         <input  type="submit"  value="Create"  /> 
     </p> 
 </fieldset> 
 }

Yukarıda ki kodda standart bir MVC Razor sayfası görülmektedir ve tüm kodu MVC oluşturdu. LabelFor, EditorFor ve ValidationFor metotları bizim veri modeli açıklalarımızı dikkate alacak ve istediğimiz önyüzü oluşturacaktır.

Görüldüğü üzere MVC veri modeli açıklamaları dikkate aldı ve gerekli şekilde önyüzü ve istemci tarafı doğrulama metotlarını oluşturdu. İstemci tarafında ki javascript fonksiyonlarının ve sunucu tarafında veri kontrollerinin otomatik olarak oluştuğuna özellikle dikkat ediniz. Biz ekstra hiç bir kodlamada bulunmadık.

Daha Fazlası

Sistem içinde bir çok genişleme noktası mevcuttur. Kendi doğrulama/validator sınıflarınızı yazabilirsiniz. Data tiplerine özel önyüz kontrolleri oluşturablirsiniz. MVC örneğimizde veriyi önyüz ve sunucu kodları arasında taşıyan binder sınıfı mevcuttur. Kendinize ait DataAnnotations niteliklerinize özel ModelBinder örneği oluşturabilirsiniz.

Sonuç

Veri modelini doğrulama yaklaşımı aslında bir ilgileri ayırma/(Speration of concers) yöntemidir. En bilinen ilgileri ayırma yöntemi Html ve css kodlarının ayrılmasıdır. DataAnnotations ile veri modeli ve veri modelini ilgilendiren veri doğrulama, görüntüleme gibi özellikler veri modeli sınıfı üzerinde turuluyor. Veri ilgilendirmeyen önyüz kodları ayrı bir yerde tutuluyor. Sunucu tarafında ki iş mantığı kodları ayrı bir alanda tutuluyor.

Veri modeli açıklamasının tüm platformlarda aynı şekilde kodlanması ve kolay anlaşılabilirlik ile birlikte sistemin bir çok genişleme noktası bulunması sistemi kullanılabilir olmasını sağlamaktadır. Ciddi bir kodlama yüküne çözüm getirmesi tüm platformlarda desteklenmesi DataAnnotations isim uzayının hayatımızda çok fazla yer alacağını göstermektedir.

Emre Coşkun

http://www.emrecoskun.net/

demo