C# Kod Standatları ve En İyi Programlama Teknikleri – Bölüm 5

13 Kas
  1. Giriş
  2. İsimlendirme ve standartları
  3. Girintiler ve aralıklar
  4. Doğru programlama teknikleri
  5. Mimari
  6. ASP.NET
  7. Yorumlar
  8. Hata ayıklama

Mimari

Serimizin bu bölümünde mimariler konusuna kısaca değinilmektedir.

  • Her zaman çok katmanlı (N-Tier) mimariyi tercih edin.
  • Veritabanı bağlantılarını arayüzün bulunduğu katmandan (UI ) yapmayın. Her zaman veritabanı işlemlerini ve ilişkilerini barındıran bir veri erişim katmanınız bulunsun. Bu sayede bugün MsSQL server yarın Oracle veya Ms Access dosyasını kullanmanızda sorun olmayacaktır.
  • Veritabanı hatalarını yakalamak için try-cache kullanın. Bu sayede connectionstring, sql komutu, stored procedure gibi yapıların hangisinde hata olduğu açığa çıkıyor olacaktır.
  • Uygulamanızı gerektiği taktirde birçok projeden(assembly) oluşacak şekilde geliştirin.

C# Kod Standatları ve En İyi Programlama Teknikleri – Bölüm 4

9 Kas
  1. Giriş
  2. İsimlendirme ve standartları
  3. Girintiler ve aralıklar
  4. Doğru programlama teknikleri
  5. Mimari
  6. ASP.NET
  7. Yorumlar
  8. Hata ayıklama

Doğru Programlama Teknikleri

  • İçeriği çok uzun olan metodlar yazmayın. Bir metod 1 – 25 satır arası uzunlukta olmalıdır. Eğer 25 satırdan uzun bir metodunuz varsa bunu alt metodlara bölmelisiniz.
  • Metod isimleri metodun ne iş yaptığını anlatır nitelikte olmalıdır. Niyeti belli etmeyen yanıltıcı isimler kullanmayın. Metod ismi açıklayıcı şeklide seçilirse metodun ne iş yaptığını belirten yorum satırları yazmamıza gerek kalmaz.

İyi Kod:

Kötü Kod:

  • Yazılmış bir metodun tek bir işi olmalıdır. Metoda yaptıracağınız iş çok küçük olsa bile, tek bir satırlık olsa bile birmetoda birden fazla işi yüklemektek kaçının.

İyi Kod:

Kötü Kod:

  • Değişken tiplerini System ad uzayındaki özel tipler yarine C# veya VB dillerine belirlenmiş standart değişken tiplerden seçin.

  • Herzaman beklenmedik durumları göz önünde bulundurun. Örneğik iki değer alabilen bir değişkeniniz varsa bu değerler dışında bir durum olabileceğini göz önünde bulundurmalısınız.

İyi Kod:

Kötü Kod:

  • Sayı değerlerini kod içine doğrudan gömmek (Hardcode) yerine Constant değişken olacak şekilde tanımlayın. Ancak constant değişkenler ilerde değiştirilme ihtiyacı duyacaksa kullanması  önerilmez. Bunun yerine configuratin dosyaları veya veritabanları tercih edilir. Eğer bir değer hiç değişmeyecek değer alacaksa constant olarak tanımlayın. Örneğin pi sayısı gibi.
  • String değişkenleri kod içine doğrudan yazmak yerine resource dosyaların kullanın.
  • String değişkenleri birbiri ile karşılaştırmadan önce UpperCase veya LowerCase dönüşümü yapın. Bu sayede karşılaştırılan kelimeler yazım olarak aynı standarda getirilerek karşılaştırma yapılmış olacak. Yani “kelime” ile “KeLiMe” karşılaştırmasında hata olmaktan kutulmuş oluruz.

  • String tiplerin boş olup olmadığı durumları test etmek için (“”) sınaması yerine String.Empty sınamasını kullanın.

İyi Kod:

Kötü Kod:

  • Üye değişkenleri (members) kullanmaktan kaçının. Ortak bir üye değişkeni tüm metodlarda kullanmak yerine lokal değişkenleri gerektiği yerlerde tanımlayın ve diğer metodlara geçirin (parametre olarak). Bu sayede değişkenin hangi metod tarafından ne zaman değiştirildiğini takip etmek kolay olur.
  • Gerekli yerlerde enum kullanın.  Ayrık değerleri göstermek için string veya numaraları kullanmaktan kaçının.

İyi Kod:

Kötü Kod:

  • Üye değişkenleri (members) public veya protected tanımlamayın. Bunun yerine bu değişkenlere özel özellikler (properties) tanımlayın.
  • Olay yakalayıcılar (Event Handler) içerisinde direk iş yapıcı kodlar bulundurmak yerine Event Handler tarafından bir metodu çağırarak metoda iş yaptırın.
  • Kod içinde fiziksel dosya yollarını (path) veya sürücü isimlerini asla elle yazmayın. Bunun yerine “application path” denilen uygulamanın göreceli yollarını kullanın.
  • Uygulamanızın her zaman “C:” sürücüsünde çalışacağını farzetmeyin. Belki bir kullanıcı “D:” sürücüsünde veya sunucuda çalışacak olabilir.
  • Uygulama başlatılırken, önce bir “öz dnetim” yaparak gerekli dosyaların olup olmadığını veya veritabanı bağlantılarının sağlanım sağlanmadığını test ederek kullanıcıyı uygun bir mesajla durumdan haberdar edin.
  • Konfigürasyon dosyası yoksa uygylama varsayılan olarak bir dosya oluşturabilmeli.
  • Konfigürasyon dosyasındaki bir ayar yanlış girlmişse uygulama bir hata fırlatmalı veya kullanıcıya doğru ayarın ne olması gerektiğini bildirmelidir.
  • Hata mesajları kullanıcıya sorunu çözebilmesi için yardımcı olmalıdır. Örneğin “Veritabanı bağlantısı sırasında bir hata oluştu. Kullanıcı adı ve şifrenizi kontrol ediniz.” gibi.
  • Bir dosya içinde birden fazla sınıf (class) bulundurmayın.
  • Çok büyük dosyalar oluşturmaktan kaçının. Bir dosya içinde binlerce satır kod olmamalıdır. Bunun yerine ayrı dosyalarda küçük sınıflar (class) halinde çalışılmalıdır.
  • AssemblyInfo dosyasına bilgileri tam olarak girin. Ad, soyad, şirket v.s gibi.
  • Eğer bir veritabanı, file stream veya soket bağlantısı açtıysanız bu bağlantıyı finally bloğunda kapatın. Bu sayede kodunuz zaten açık olan bağlantıyı açmaya çalışıyorsunuz şeklinde hatalardan arınmış olur.
  • Bir döngü içinde string nesnelerini işlemek zorunda kaldığınızda string yerine StringBuilder nesnelerini tercih edin. .Net’te String nesnesi garip bir şekilde çalışır. Bir stringe bir ekleme yaptığınızda eski string silinerek yeni bir nesne oluşturulur. Bu da pahalı bir yöntem olacaktır.

Aşağıda bu durumu yansıtan bir örnek mevcut:

   public string ComposeMessage (string[] lines)
   {
      string message = String.Empty;

      for (int i = 0; i < lines.Length; i++)
      {
        message += lines [i];
      }
      return message;
   }

StringBuilder nesnesinin kullanıldığı bir örnek ise şu şekilde olacaktır:

   public string ComposeMessage (string[] lines)
   {
     StringBuilder message = new StringBuilder();

     for (int i = 0; i < lines.Length; i++)
     {
        message.Append( lines[i] );
     }

     return message.ToString();
   }

C# Kod Standatları ve En İyi Programlama Teknikleri – Bölüm 3

3 Kas
  1. Giriş
  2. İsimlendirme ve standartları
  3. Girintiler ve aralıklar
  4. Doğru programlama teknikleri
  5. Mimari
  6. ASP.NET
  7. Yorumlar
  8. Hata ayıklama

Girintiler ve aralıklar

  • Girinti yapmak için TAB tuşunu kullanın. Boşluk (SPACE) tuşunu kullanmayın.
  • Yorum satırları kod satırlarıyla aynı hizada olmalıdır.

İyi Kod:

Kötü Kod:

  • Süslü parantzler ( {} ) kodlar ile aynı seviyede olmalıdır.

  • Gruplandırdığınız kod blokları arasında bir satır boşluk bırakın.

İyi Kod:

Kötü Kod:

  • Sınıf içinde her bir metod arasında sadece bir satır boşluk olmalıdır.
  • Süslü parantezler if, for gibi kodlarla aynı satırda olmamalı ayrı bir satırda olmalıdır.

İyi Kod:

Kötü Kod:

  • Her operator ve parantezden önce bir boşluk bırakın

İyi Kod:

Kötü Kod:

  • Birbiri ile alakalı kod parçalarını guruplamak için #region kodunu kullanın. Bu kod arasında kalan kodları kapatarak saklamak mümkündür.

  • Private üye değişkenleri,  metodları ve özellikleri dosyanın üst kısmında public olanları ise dosyanın alt kısmında tutun.

C# Kod Standatları ve En İyi Programlama Teknikleri – Bölüm 2

31 Eki
  1. Giriş
  2.  İsimlendirme ve standartları
  3. Girintiler ve aralıklar
  4. Doğru programlama teknikleri
  5. Mimari
  6. ASP.NET
  7. Yorumlar
  8. Hata ayıklama

İsimlendirme ve standartları

Serimizin ikinci bölümüyle yeniden birlikteyiz. Bu bölümde kodlama yaparken alan, özellik, sınıf gibi yapıların isimlendirmelerini yaparken dikkat etmemiz gereken noktaları konuşacağız.

İsimlendirme standartlarına giriş yaparken makale boyunca sıklıkla karşılaşacağımız Pascal Casing ve Camel Casing  kavramlarından bahsetmemiz gerekiyor: 

Pascal Casing: Kelimelerin ilk harfleri büyük geri kalan harfleri küçük yazılır.

Örnek: ProductName

Camel Casing: İlk kelimenin ilk harfi hariç kelimelerin baş harfleri büyük diğer harfler küçük yazılır.

Örnek: productName

  • Sınıf adlandırmalarında Pascal Casing yöntemini kullanın.

  • Metod adlandırmalarında Pascal Casing  yöntemini kullanın.

  • Değişken isimlerinide ve metod parametrelerinde Camel Casing yöntemini kullanın.
  • Arayüz (Interface) isimlendirmelerini yaparken “I” ön ekini kullanın.(Ör: IProduct)
  • Değişken isimlendirmelerinde Macar (Hungarian) notasyon tercih etmeyin. Önceleri  programcıların değişken kelimeleri arasında kullandığı ”_” alt tire karakteri .net kod standartlarında tercih edilmez. (ÖR: String m_name;). Bunun yerine Camel Casing kullanılır.
  • Değişkenler için anlamlı ve açıklayıcı kelimeler kullanın. Kısaltma kullanmayın.

İyi Kod:

string address

int salary

Kötü Kod:

string nam

string addr

int sal

  • Tek karakterlik değişken işimleri (i, n, s gibi) kullanmayın. Bunun yerine index, temp gibi kelimeler kullanın. Ancak döngülerde iterasyon için kullanılan değişkenler bu durum haricindedir.

for ( int i = 0; i < count; i++ )
{

……..

}

  • Lokal değişkenler için (_) alt tire karakterini kullanmayın.
  • Değişken isimlerini C# anahtar kelimelerine benzer olacak şekilde seçmeyin.
  • Mantıksal (boolean) değişkenlerin önünde (is) veya benzer ön ekler kullanın. (ör: private bool isFinished)
  • UI elemanlarını birbirinden ayırabilmek için uygun bir önek kullanın.
Control Prefix
Label lbl
TextBox txt
DataGrid dtg
Button btn
ImageButton imb
Hyperlink hlk
DropDownList ddl
ListBox lst
DataList dtl
Repeater rep
Checkbox chk
CheckBoxList cbl
RadioButton rdo
RadioButtonList rbl
Image img
Panel pnl
PlaceHolder phd
Table tbl
Validators val
  • Sınıfların (Class) bulunduğu fiziksel dosya isimleri sınıf ismi ile aynı olmalıdır. Örneğin HelloWorld sınıfı için dosya adı helloworld.cs veya HelloWorld.cs olabilir.
  • Dosya isimleri için Pascal Casing kullanın.

Serinin bu bölümü umarım anlaşılabilmiştir. Bir sonraki bölümde görüşebilmek dileğiyle.

C# Kod Standatları ve En İyi Programlama Teknikleri – Bölüm 1

30 Eki
  1. Giriş
  2. İsimlendirme ve standartları
  3. Girintiler ve aralıklar
  4. Doğru programlama teknikleri
  5. Mimari
  6. ASP.NET
  7. Yorumlar
  8. Hata ayıklama

Giriş

C# Kodlama standartlarının anlatıldığı 8 bölümlük serimize giriş yapmış bulunuyoruz.

Herkes birkaç aylık programlama eğitimi sonrasında kod yazar hale gelebilir. Kolayca çalışan uygulamalar ortaya çıkarabilir. Ancak işi doğru bir şekilde yapmak, daha fazla çalışma gerektirir.

Şuna inanmak gerekir ki programcıların çoğu “çalışan kod” değil “iyi kod” yazmak ister. “İyi kod” yazmak öğrenilmesi gereken gereçek bir sanattır.

“İyi kod” yazmanın tanımını herkes farklı bir şekilde yapabilir. Bence iyi kodun şu özellikleri taşıması gerekir.

  • Güvenilir olamlıdır.
  • Sürdürülebilir olmalıdır. Yani bakımı kolay olmalıdır.
  • Verimli olmalıdır.

Birçok geliştirici kodun sürdürülebilir ve güvenilir olmasından çok, yüksek performanslı olmasını göz önünde tutar. Ancak uzun vadede (Yatırım açısından) verimlilik ve performans, güvenilirlik ve bakımdan sonra gelir. Yazdığınız kod güvenilir ve sürdürülebilir değilse, siz (veya şirketiniz) her defasında sorunların tespiti ve uygulamanın akışını anlayabilmek için çok fazla zaman harcamak zorunda kalacaktır. Unutmayın, yapılan her fazla mesainin ardında plansız yapılmış işler vardır.

Microsoft ASP.NET takımından Syn. Stephen Walter bir hikayesinde yazılım geliştirmeye ilk başladığı zamanlarda iyi yazılım için “Good software is software that works as you intended.” diyoru. Yani iyi yazılım istediğiniz gibi çalışan yazılımdır. Ancak daha sonraları büyük şirketlere girdiğinde geliştirilen yazılımın odak noktasının hızlı yazılım üretmek değil, yazılan kodun bakımının kolay olması olduğunu görüyor. Stephen Walter fikrini değiştiriyor ve “Good software is software that works as you intended and that is easy to change” diyor. Yani iyi yazılım bakımı kolay olan ve istediğiniz gibi çalışan yazılımdır diyor.

Serinin devamında isimlendirme ve standartları ile kodlama olaylarını örneklerle anlatarak devam ediyor olacağız.

Asp.net MVC Razor Hepler ile Durum Çubuğu Yapmak

15 Eyl

Bu yazıda tamamen kendi emeklerimizle, jquery veya başka hazır kütüphane yardımı almadan bir ilerleme çubuğu(progres bar) yapmaya çalışacağız.

Yeni bir ASP.NET MVC projesi yaratarak işe başlıyoruz.

Projelerde genellikle ingilizce değişken adları kullanmaya çalışıyorum ki yazının ingilizcesini hazırlarsam çalışan örnek projeyi değiştimeye gerek kalmasın.

Örnek projede içiçe iki div etiketleri kullanıyoruz. Dıştaki div kapsül, içteki div ise durumu göstermeye yarayacak.

Çalışan uygulama görüntüsünü şu şeklide verelim ki daha fazla merak uyandırmadan düşünce geliştirmeye geçelim.

Yukarda görüldüğü gibi iç içe iki div etiketi içersinde son duruma ait yüzdelik gösterim yapılmış durumda.

İlk olarak css dosyamız içerisinde durum göstergesi için gerekli ayarlamalar şu şekilde belirliyoruz.

#progressBar{
   border:1px solid #4771a5;
   height:15px;
}

#progressInner{
   background-color:#96b1d2;
   height:15px;
}

Daha sonra razor view ortamında bir helper kodluyoruz. Helper ise aşağıdaki şekilde olacaktır.

@helper  ProgressBar(double BarWidth, double InnerWidth){

   BarWidth = BarWidth < 0 ? 100 : BarWidth;
   InnerWidth = InnerWidth < 0 ? 100 : InnerWidth;
   BarWidth = BarWidth > 400 ? 400 : BarWidth;

   InnerWidth = InnerWidth > BarWidth ? InnerWidth = BarWidth : InnerWidth;

   string barWidth = BarWidth.ToString() + "px";
   string innerWidth = InnerWidth.ToString() + "px";
   string persantage = ((int)(InnerWidth / BarWidth * 100)).ToString()+"%";

   <div id="progressBar"  style="width:@barWidth">
       <div id="progressInner" style="width:@innerWidth"></div>
   </div>
   <label>@persantage</label>

}

Yukarda ProgressBar adında bir helper oluşturulmuş durumda. Helper içerisinde kullanıcının abuk değerler verip gösterge çubuğunu sapıtmaması için bir dizi önlemler alıyoruz. Bar ve Inner değerinin sıfırdan küçük veremesin, dolan mavi kısım Bar değerini geçemesin v.s gibi. Duruma göre daha fazla önlem alınabilir.

Burada dikkat edilmesi gereken husus şudur ki, html etiketlerinin css özellikleri dinamik olarak değişmektedir.

Geriye kaldı ki bu helper nasıl kullanılacak. O da şu şekilde.


<h2>Razor Helper Progress Bar</h2>

@ProgressBar(300, 120)

Evet sadece bu kadar. ProgressBar helper’ı artık farklı denemelerle kullanılabilir duruma getirdik.

Nerelerde kullanılabilir?

Veritabanından çekilen değerleri göstermek için ideal bir yöntem olabilir. Örneğin bugün en çok satış yapan çalışanın yaptığı satış bugün yapılan toplam satışların yüzde kaçına tekabül ediyor.

Neden bununla uğraşalım?

Çünkü koda tamamen hakimiz. Yukardaki örnekte Bar yüksekliğini css içerisinde sabitledim. İstersek dışarı çıkarıp Width özelliği gibi dinamik hale getirebiliriz.

Soru: Sizce ProgressBar metodunda double parametreler string dönüşümü yapılmadan style içersine nasıl yerleştirilir?

Uygulamanın çalışan kodları buradadır.

Umarım faydalı olmuştur herkese iyi çalışmalar.

Silverlight Client Access Policy ve Cross-Domain sorunu

8 Eyl

Bu yazımızda silverlight uygulamasına başka bir site veya projedeki servisi referans verdiğimizde karşılaşılan sorunlardan ve çözümlerinden bahediyor olacağız.

Sorun: Tarayıcıların çalıştıkları domain dışından veri alma ve gönderme sorunu. Bu demek oluyor ki silverligth uygulamsından, dışardaki bir uygulamaya ulaşmak istediğimizde cross-domain problemi ile karşılaşacağız.

Bir uygulama üzerinden gidecek olursak, bir solution üzerine CrossService adında bir WCF Service Application birde Silverlight Application ekleyerek başlayabiliriz.

CrossService projesine başka bir alan adı muamelesi yaparak FarService adında bir servis ekliyoruz. Bu servisimiz içerisinde basit olması açısından mesaj veren bir metod barınmaktadır.
IFarService interface


[ServiceContract]
public interface IFarService
{
    [OperationContract]
    string  ServiceMessage();
}

FarService sınıfı


public class FarService : IFarService
{
     public string ServiceMessage()
     {
       return String.Format("Ben Uzak servisten geliyorum. Tahih :{0}", DateTime.Now);
     }
}

Silverlight uygulamamızın barındığı web uygulamasına ise aynı domainde bulunduğunu belirtmek açsından LocalService adında bir servis ekliyoruz.

ILocalService interface

[ServiceContract]
public interface ILocalService
{
    [OperationContract]
    string  ServiceMessage();
}

LocalService sınıfı

public class LocalService : ILocalService
{
    public string ServiceMessage()
    {
         return String.Format("Ben Yakın servisten geliyorum. Tahih :{0}", DateTime.Now);
    }
}

Şu anda servislerimiz hazır ve uygulamaya dahil edilmeye hazır.
Silverlight uygulamamıza Add Service Reference… diyerek referansları ekliyouz.

Referanslar eklendiğinde aşağıdaki görüntü oluşacaktır.

Artık servis referansları yardımıyla servislerdeki ServiceMessage() metodlarını çağırabiliriz.

MainPage.xaml sayfasının tasarım kısmını şu şekilde düzenliyouz.

Kod kısmına gelecek olursak:

public partial class MainPage : UserControl
{
    FarServiceReference.FarServiceClient uzakServis
                  = new FarServiceReference.FarServiceClient();

    LocalServiceRefference.LocalServiceClient yakinServis
                  = new LocalServiceRefference.LocalServiceClient();

    public MainPage()
    {
        InitializeComponent();
    }

    private void btnUzak_Click(object sender, RoutedEventArgs e)
    {
        uzakServis.ServiceMessageAsync();
        uzakServis.ServiceMessageCompleted += (snd, ea) =>
        {
            lblUzak.Content = ea.Result;
        };
    }

    private void btnYakın_Click(object sender, RoutedEventArgs e)
    {
        yakinServis.ServiceMessageAsync();
        yakinServis.ServiceMessageCompleted += (snd, ea) =>
        {
           lblYakin.Content = ea.Result;
        };
   }
}

Görüldüğü üzere iki butondan biri uzak servisi diğeri yakın servisi çağırıyor olacak. Sonrasında servislerden gelen mesajlar  Label üzerine aktarılıyor olacaktır.

Yakın serviste bir sorun yok şu anda. Acak uzak servis için CrossService projesi içinde clientaccesspolicy.xml adında bir dosya mevcut. Silverlight uzak alan adına gittiğinde bu dosya mevcut mu diye bakar. Ki bu dosya içierisindeki ayarlara göre erişim yetkisine sahip mi değilmi anlayacak.

Xml dosya içeriği şu şekilde olacaktır:

 <?xml version="1.0" encoding="UTF-8"?>
 <access-policy>
   <cross-domain-access>
    <policy>
     <allow-from http-request-headers="*">
      <domain uri="*"/>
     </allow-from>
    <grant-to>
      <resource include-subpaths="true" path="/"/>
    </grant-to>
    </policy>
  </cross-domain-access>
 </access-policy>

Dikkat: Eğer clientaccesspolicy.xml dosyası uzak uygulamada olmasaydı şu şekilde bir sorunla karşılaşacaktık.

Hata: “An error occurred while trying to make a request to URI ‘http://localhost:1763/FarService.svc’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.”

Uygulamanın çalışan kodunu buradan indirebilirsiniz. Umarım faydalı olmuştur. Herkese iyi çalışmalar.

Asp.net Mvc Model Binding

5 Eyl

MVC mimarisinde açıklanması gereken bir konu da Model Binding konusudur. Bu yazıda Model Binding konusunu incelemeye çalışacağız.

Tanım: Model Binding HTTP request ile gelen verilerinin ayrıştırılarak ilgili Controller’da bulunan Action metod parametrelerine ve uygun .NET tiplerine dönüştürülmesi işlemidir.

Eğer bir action metod parametre almışsa Model Binding işlemi gerçekleşmektedir.

Arka planda gerçekleşen olaylar: Şimdi aşağıdaki gibi Index adında, string türünde bir tane parametre alan bir Action metod olduğunu varsayalım.

public ActionResult Index(string name)

Index Action’ı çağırılmadan önce arka plan işlemlerini yönetecek iki önemli bileşen vardır. Bunlar ValueProviderDictionary ve DefaultModelBinder’dır.

ValueProviderDictionary: HTTP request ile gelen parametreleri çekerek string halinde depolar. Bu işlem aşağıdaki sırayla gerçekleşir.

  • Request.Form[“name”] var mı diye bakar.
  • Yoksa RouteData.Values[“name”] var mı diye bakar.
  • Yoksa Request.QueryString[“name”] var mı diye bakar.
  • Yoksa null değer döndürür.

Böylece ValueProviderDictionary  HTTP request ile gelen değerleri elde etmiş olur.

DefaultModelBinder: ValueProviderDictionary sınıfının elde ettiği değerleri uygun .NET objelerine gönüştürme görevini üstlenir. Yukardaki örnekte “name” parametresi zaten string tipindedir. Bu durumda DefaultModelBinder dönüşüm yapmak durumunda değildir. Fakat aşağıdaki gibi int veya başka türde parametre alan Action metodlar olabilir.

Durum 1

public ActionResult Index(int id, decimal rate)

Bu durumda DefaultModelBinder sınıfı parametre tip dönüşümlerini otomatik olarak yapacaktır.

Durum 2

Şu ana kadar olan kısımda HTTP request ile gelen isteklerin ayrıştırılıp uygun .NET tiplerine dönüştürüldüğünü gördük. Ancak aşağıdaki gibi özel bir tipin modele bind edilmesi gereken bir durum sözkonusu olabilir.

public ActionResult Index(Person person)

DefaultModelBinder yukarıdaki gibi özel bir .NET tipi ile (Person) karşılaştığında Reflection yardımına koşar. Reflection sayesinde özel tipe ait tüm public özellikler ValueProviderDictionary sınıfı tarafından sağlanan değerleri alır.

Binding

Model binding işlemini bu noktadan itibaren bir örnek yardımıyla incelemeye çalışalım. Örneğimizde bir Person model nesnesinin nasıl bind edildiğini inceliyor olacağız.

public class Person
{
     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }
}

Autoproperty’ler yardımıyla oluşturulmuş Person model tipimiz yukarıda basit bir şekilde oluşturulmuş durumda.

View tarafında bir form oluşturularak, oluşturulan formun Controller tarafında bir action metoda post edilmesi gerekmektedir.

@model MvcModelApp.Models.Person 

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Kişi Bİlgileri</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

Controller tarafında ise DefaultModelBinder tarafından doldurulmuş person nesnesinin kullanılması gerekmektedir.

      [HttpPost]
        public ActionResult CreatePerson(Person person)
        {
            // person nesnesi form bilgileri ile doldurulmuş durumda
            // person nesnesi artık gerekli işlem için 
            // (database, xml kaydı v.s) kullanılabilir

            return RedirectToAction("Index", "Home");
        }

Yukarıdaki action metodunun parametresi olan Person nesnesi DefaultModelBiner tarafından doldurulmuştur.  @model MvcModelApp.Models.Person ile view sayfasının modelinin belirlendiğini görüyoruz. Controller tarafında CreatePerson metoduna post edilen form bilgileri Person nesnesine doldurulmaktadır.

Bu işlem şöyle gerçekleşmektedir: DefaultModelBinder action metodun aldığı parametre tipinden (Person) bir nesne oluşturarak Property’lerini view sayfasından gelen form bilgileri ile eşleştirerek doldurmaktadır.

Umarım faydalı bir yazı olmuştur. Herkese iyi çalışmalar. Bir sonraki yazıda görüşmek üzere.

C# Dilinde Kullanılan Faydalı Operatörler

28 Ağu

(??)  “null coalescing” Null kontrol operatörü

Bu operatör nullable(null değer alabilir) bir değişkenin null oluğ olmadığını kontrol eder.

Örnek:
               string name = "Product";
               string info = name ?? "product name is null"

(?:)  Mantıksal Sınama Operatörü

Bu operatör mantıksal bir sınamayı ifadeyi temsil eder. if sınamasının kısa yazım şeklidir.

Kullanımı:
               condition ? first_expression : second_expression;
               şart ? birinci_durum : ikinci_durum;

Örnek:
               if(x != 0.0) s = Math.Sin(x)/x; else s = 1.0;
               s = x != 0.0 ? Math.Sin(x)/x : 1.0;

Nullable<> (?) operatörü

Örnek: public int? Command { get; set; } şeklindeki bir tanımlamada ? ile Command property’nin null değer alabileceği ifade ediliyor.

Örnek:
              public Nullable<int> Command {get; set;}

(::) operatörü

Bazı kütüphanelere extern alias tanımlaması yapılır. Harici isim takma şeklinde Türkçeleştirilebilir. .NET’te birçok noktada global:: şeklinde tanımlamalar bulunur. Amaç aynı isimdeki sınıfların birbirini ezmesini engellemek ve her iki sınıfada farklı isimler vererek kullanıma sunmaktır.

Örnerk:
              public global::System.Int32 id

Asp.net MVC ActionMethodSelector Attribute

26 Ağu

Bu yazımızda controller action metodları çalıştığı durumlarda action metodunu kontrol eden kendi attribute sınıfımızı nasıl oluşturabileceğimiz üzerinde duracağız. Kendi özel attribute sınıfımızı oluşturmak için yazdığımız sınıfı ActionMethodSelectorAttribute sınıfından türetmemiz gerekiyor.

Bu sınıf ileri düzeyde oluşturulmuş bir sınıf olacak. Miraslama işlemi ile oluşturduğumuz sınıfa ActionMethodSelectorAttribute sınıfından gelen IsValidForRequest() adında tek bir metod olacaktır.

    public class AjaxMethod : ActionMethodSelectorAttribute

{

public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)

{

if (!controllerContext.HttpContext.Request.IsAjaxRequest())

{

throw new Exception(“Bu metod [” + methodInfo.Name + “] sadece Ajax request için tanımlanmıştır.”);

}

 

return true;

}

}

 

Oluşturulan attribute bir action metoda şu şekilde uygulanmaktadır:

        [AjaxMethod]
        public ActionResult Unknown()
        {
            return View();
        }

Eğer Unknown() metoduna Ajax request haricinde bir request gelirse aşağıdaki gibi bir hata sayfasıyla karşılaşıyor olacağız.

Bir sonraki yazıda görüşmek üzere herkese iyi çalışmalar.