Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Cenk Özdemir
Cenk Özdemir
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
4 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: datakeynames datakeys eventargs gridview indeksli istedigimiz kolonu productid productid protected satirin sender string verinin viewstate ASP.NET Cenk Özdemir
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : ASP.NET
Yayınlanma Tarihi : 19.2.2007
Okunma Sayısı : 50830
Yorum Sayısı : 1     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 20.4.2024
Turhal Temizer
Mac OS/X Removing CUDA 20.4.2024
Burak Selim Şenyurt
Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı 20.4.2024
Burak Selim Şenyurt
Matematik ve Oyun Programlama - Missile Command - Final 20.4.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
DataGrid ve GridView Kontrollerinde Görünmez Kolonlar
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

ASP.NET uygulamalarında, verileri tablo biçiminde görüntülerken, bazı kolonları kullanıcılardan saklamak isteyebiliriz.Bu ihtiyacın birkaç sebebi olabilir.Örneğin tablomuzun primary key kolonu, genelde programcının kullanacağı bir değeri içerir ve kullanıcılar tarafından görülmesi tercih edilmeyebilir.Benzer şekilde programcının, sayfadaki veritabanı işlemlerinde kullanmak üzere tabloya aldığı; ancak kullanıcıların görmelerini istemediği kolonlar olabilir. İşte bu gibi durumlarda akla ilk gelen yol, ilgili kolonun visible özelliğine false atamaktır.

Web’te kullandığımız DataGrid ve GridView kontrolleri arasında, görünmez kolonların ( visible özelliklerine false atanmış olan kolonlar ) işleyişi bakımından önemli farklar mevcuttur. Eğer veritabanından gelen bilgi içerisinde, kullanıcılardan saklamak istediğimiz kolonlar var ise her iki kontrol (DataGrid ve GridView) için farklı şekilde düşünmemiz gerekir. Bu durum, GridView kontrolünün görünmez kolonlara veri bağlamamasından kaynaklanır. Şimdi, isterseniz, bir web site projesi üzerinden ilerleyerek problemi daha net görmeye ve çözüm yollarını incelemeye çalışalım.

Öncelikle yeni bir web site projesi açıp, sayfamızı aşağıdaki gibi oluşturalım. Ben, yapacağımız örneklerde AdventureWorks veritabanını kullanacağım. Eğer AdventureWorks sisteminizde bulunmuyor ve başka bir veritabanında çalışıyorsanız, bağlantı ayarının yanı sıra HeaderText ve DataField bildirimlerini de gelen veriye göre düzenlemeniz gerekir.

default.aspx
<asp:TextBox ID="txtRowIndex" runat="server" />
<asp:Button ID="btnGoruntule" runat="server" Text="Görüntüle" OnClick="btnGoruntule_Click" />

<asp:SqlDataSource ID="dsProduct" runat="server"
   ConnectionString="data source=localhost;database=AdventureWorks;integrated security=SSPI"
   SelectCommand="SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product">
</asp:SqlDataSource>

<asp:DataGrid ID="dgProducts" runat="server" AutoGenerateColumns="False" OnItemDataBound="dgProducts_ItemDataBound" >
   <Columns>
      <asp:TemplateColumn HeaderText="RowIndex">
         <ItemTemplate>
            <asp:Label ID="lblRowIndex" runat="server"></asp:Label> <%-- Satır numalarını tutmak için faydalandığımız Label --%>
         </ItemTemplate>
      </asp:TemplateColumn>
      <asp:BoundColumn HeaderText="ProductID" DataField="ProductID"  Visible="False" /> <%-- ProductID kolonunu gizlemek istiyoruz --%>
      <asp:BoundColumn HeaderText="Name" DataField="Name" />
      <asp:BoundColumn HeaderText="ListPrice" DataField="ListPrice" />
      <asp:BoundColumn HeaderText="SellStartDate" DataField="SellStartDate" />
   </Columns>
</asp:DataGrid>

default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
   dgProducts.DataSource = dsProduct;
   dgProducts.DataBind();
}

protected void btnGoruntule_Click(object sender, EventArgs e)
{
   int satirSayisi=Convert.ToInt16(txtRowIndex.Text);
   string gelenDeger = dgProducts.Items[satirSayisi].Cells[1].Text; //İstenen satırın ProductID değeri
  
   Response.Write(satirSayisi+" indeksli verinin ProductID değeri:"+gelenDeger);
}

int index = 0;
protected void dgProducts_ItemDataBound(object sender, DataGridItemEventArgs e)
{
   //Template kolonumuzda satır numaralarını oluşturuyoruz

   DataGridItem gelenSatir=e.Item;

   try // e parametresiyle yakaladağımız satırın RowType özelliği hataya sebep verecek bir değer içeriyorsa görmezden gel ( Header gibi )
   {
      Label lblIndex = (Label)gelenSatir.Cells[0].FindControl("lblRowIndex");
      lblIndex.Text = index.ToString();
      index++;
   } catch { }
}
Sayfamızı oluşturduktan sonra çalıştırıp test edelim.



Açılan sayfada TextBox içerisine tablodaki RowIndex’lerden birini yazıp ProductID değerini elde edebiliyoruz. Yani erişilen kolonun görünür olup olmaması herhangi bir sorun teşkil etmiyor.
Şimdi bir de GridView için, aynı işlemin ne gibi sonuçlar doğuracağını görmek amacıyla projemize yeni bir web form ekleyip aşağıdaki gibi tasarlayalım.

default2.aspx
<asp:TextBox ID="txtRowIndex" runat="server" />
<asp:Button ID="btnGoruntule" runat="server" Text="Görüntüle" OnClick="btnGoruntule_Click" />

<asp:SqlDataSource ID="dsProduct" runat="server"
   ConnectionString="data source=localhost;database=AdventureWorks;integrated security=SSPI"
   SelectCommand="SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product">
</asp:SqlDataSource>

<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvProducts_RowDataBound">
   <Columns>
      <asp:TemplateField HeaderText="RowIndex">
         <ItemTemplate>
            <asp:Label ID="lblRowIndex" runat="server" />
         </ItemTemplate>
      </asp:TemplateField>
      <asp:BoundField HeaderText="ProductID" DataField="ProductID" Visible="False" /> <%-- ProductID kolonunu gizlemek istiyoruz --%>
      <asp:BoundField HeaderText="Name" DataField="Name" />
      <asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
      <asp:BoundField HeaderText="SellStartDate" DataField="SellStartDate" />
   </Columns>
</asp:GridView>

default2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
   gvProducts.DataSource = dsProduct;
   gvProducts.DataBind();
}

protected void btnGoruntule_Click(object sender, EventArgs e)
{
   int satirSayisi = Convert.ToInt16(txtRowIndex.Text);
   string gelenDeger = gvProducts.Rows[satirSayisi].Cells[1].Text; //İstenen satırın ProductID değeri
  
   Response.Write(satirSayisi + " indeksli verinin ProductID değeri:" + gelenDeger);
}

int index = 0;
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
   //Template kolonumuzda satır numaralarını oluşturuyoruz

   GridViewRow gelenSatir = e.Row;

   try
   {
      Label lblIndex = (Label)gelenSatir.Cells[0].FindControl("lblRowIndex");
      lblIndex.Text = index.ToString();
      index++;
   } catch { }
}
Default2.aspx sayfasını çalıştırıp, herhangi bir satırın ProductID değerini elde etmeye çalışalım.



Gördüğünüz gibi, istediğimiz sonucu alamamıza rağmen, çalışma zamanında bir istisnayla ( exception ) karşılaşmıyoruz. Başka bir deyişle, gizlenmiş ProductID kolonu bize değer olarak boş bir string ifadesi döndürüyor. Peki sebep nedir?

Her şey güvenlik için

DataGrid kullandığımızda,kolonun visible özelliğinin true ya da false olduğuna bakılmaksızın veri bağlanıyor ve bu bilgi ViewState içerisinde yerini alıyor.Eğer ihtiyacımız olan şey tablodaki bir kolonu kullanıcılardan saklamaksa, tahmin edersiniz ki, bu pek güvenli bir yöntem değildir.ViewState bilgisi enkript edilmediğinde istemciler tarafından okunur formatta elde edilebilir.Bu da sayfamız için önemli bir güvenlik açığıdır.İşte bu yüzden, ASP.NET 2.0 ile birlikte gelen GridView kontrolünde, gizlenmek istenen kolonların korunumu adına alınmış bazı önlemler vardır.Yaptığımız örnekte yaşadığımız problem de, aslında, görünmeyen kolonlara veri bağlanmamasından kaynaklanmaktadır.Öyleyse GridView’de bir kolonu görünmez yapamıyorsak, gizlemek istediğimiz bir kolon olursa nasıl bir yol izleyebiliriz?Bu amaçla GridView kontrolü içerisinde yer alan DataKeys özelliğinden faydalanacağız.

ViewState bilgisi her ne kadar okunamaz görünse de, Base64 encoding yapılarak elde edilmiş basit bir değerdir ve çeşitli araçlarla okunur hale getirilmesi oldukça basittir.Bu yüzden ViewState içerisinde kredi kartı bilgisi gibi önem arz eden verileri saklamak çok tehlikeli sonuçlar doğurabilir.
DataKeys kullanımı

Default2.aspx sayfamızı aşağıdaki gibi değiştirelim.

default2.aspx
<asp:TextBox ID="txtRowIndex" runat="server" />
<asp:Button ID="btnGoruntule" runat="server" Text="Görüntüle" OnClick="btnGoruntule_Click" />

<asp:SqlDataSource ID="dsProduct" runat="server"
   ConnectionString="data source=localhost;database=AdventureWorks;integrated security=SSPI"
   SelectCommand="SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product">
</asp:SqlDataSource>

<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvProducts_RowDataBound" DataKeyNames="ProductID" >
   <Columns>
      <asp:TemplateField HeaderText="RowIndex">
         <ItemTemplate>
            <asp:Label ID="lblRowIndex" runat="server" />
         </ItemTemplate>
         </asp:TemplateField>
      <asp:BoundField HeaderText="Name" DataField="Name" />
      <asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
      <asp:BoundField HeaderText="SellStartDate" DataField="SellStartDate" />
   </Columns>
</asp:GridView>

Farkettiyseniz,DataKeyNames özelliğine ProductID değerini atadıktan sonra GridView’e bağladığımız kolonlar arasından ProductID’yi çıkarıyoruz.Aslında çıkarıp çıkarmamazın bir önemi yok.Daha önce dediğimiz gibi GridView içerisindeki görünmez kolonlara veri bağlanmıyor.Biz DataKeyNames özelliğini kullanarak ilgili verilerin DataKeys koleksiyonunda tutulacağını söylüyoruz.Dolayısıyla veriye bu özellik yardımıyla ulaşacağımız için ayrıca bir kolon eklenmesine gerek kalmıyor. Ardından kod tarafına geçip, DataKeys özelliği yardımıyla ProductID değerlerine erişelim.
 
default2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
   gvProducts.DataSource = dsProduct;
   gvProducts.DataBind();
}

protected void btnGoruntule_Click(object sender, EventArgs e)
{
   int satirSayisi = Convert.ToInt16(txtRowIndex.Text);
   string gelenDeger = gvProducts.DataKeys[satirSayisi].Value.ToString(); //İstenen satırın ProductID değeri
   Response.Write(satirSayisi + " indeksli verinin ProductID değeri:" + gelenDeger);
}

int index = 0;
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
   //Template kolonumuzda satır numaralarını oluşturuyoruz

   GridViewRow gelenSatir = e.Row;

   try
   {
      Label lblIndex = (Label)gelenSatir.Cells[0].FindControl("lblRowIndex");
      lblIndex.Text = index.ToString();
      index++;
   } catch { }
}
Artık default2.aspx sayfamızı çalıştırdığımızda, istenen satırın ProductID değerini elde edebildiğimizi görüyoruz.



Yaptığımız tek şey, gizlemek istediğimiz kolonu DataKeyNames özelliğinde belirtmektir. Bundan sonra, DataKeys içerisindeki Key tipinden nesnelere erişebiliyor ve ProductID değerlerini elde edebiliyoruz. ( Value özelliği aracılığıyla )

Gelelim bu yöntemi daha güvenli kılan şeyin ne olduğuna. GridView’de bir kolonu gizlediğinizde, bu verinin, korunması gereken bir veri olduğu kabul edilir. Ancak kolona bağlanan veri, ViewState ile birlikte istemcilere okunur formatta ( enkript edilmemişse ) ulaşacağından; GridView, programcıyı DataKeys kullanmaya zorlar.Çünkü biz DataKeyNames özelliğine değer atadığımızda, farkında olmadan ViewState ve ControlState’in enkript edileceğini de söylemiş oluyoruz ve böylece içeriğin korunumu sağlanıyor.

ASP.NET 2.0’la gelen bu yenilik güvenlik açısından faydalı görünüyor; ancak, tahmin edersiniz ki, DataKeyNames kullanmak, performans kaybına ve sayfa boyutunun artmasına neden oluyor.Eğer performans kaygınız varsa ve DataKey değerlerinin istemcilere açık şekilde gitmesi bir sorun yaratmıyorsa,enkript işlemini engelleyerek belli bir performans artışı sağlayabilirsiniz.Bunun için web.config içerisinden system.web altındaki pages tagının viewStateEncryptionMode özelliğine "Never" değerini atamak gerekir. ( Varsayılan değeri "Auto" olduğu için - herhangi bir ayar yapmadıysanız - DataKeyNames’e değer atadığınızda ViewState mutlaka enkript edilir. )

<pages viewStateEncryptionMode="Never" />

DataKeys, ControlState içerisinde tutulur.
DataKeyNames, DataKeyField özelliğine benzer olup, önemli bir farkı çoklu kolon kullanımına izin vermesidir.Bunu nasıl yapacağımızı görmek amacıyla bir web form daha yaratalım ve sayfaya aşağıdaki kodu ekleyelim.

default3.aspx
<asp:TextBox ID="txtRowIndex" runat="server" />
<asp:Button ID="btnGoruntule" runat="server" Text="Görüntüle" OnClick="btnGoruntule_Click" />

<asp:SqlDataSource ID="dsProduct" runat="server"
   ConnectionString="data source=localhost;database=AdventureWorks;integrated security=SSPI"
   SelectCommand="SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product">
</asp:SqlDataSource>

<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvProducts_RowDataBound" DataKeyNames="ProductID,Name" >
   <Columns>
      <asp:TemplateField HeaderText="RowIndex">
         <ItemTemplate>
            <asp:Label ID="lblRowIndex" runat="server" />
         </ItemTemplate>
      </asp:TemplateField>
      <asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
      <asp:BoundField HeaderText="SellStartDate" DataField="SellStartDate" />
   </Columns>
</asp:GridView>

default3.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
   gvProducts.DataSource = dsProduct;
   gvProducts.DataBind();
}

protected void btnGoruntule_Click(object sender, EventArgs e)
{
   int satirSayisi = Convert.ToInt16(txtRowIndex.Text);
  
   string gelenProductID = gvProducts.DataKeys[satirSayisi].Values[0].ToString(); //İstenen satırın ProductID değeri
   string gelenName = gvProducts.DataKeys[satirSayisi].Values[1].ToString(); //İstenen satırın Name değeri
  
   Response.Write(satirSayisi + " indeksli verinin ProductID değeri:" + gelenProductID + "<br>");
   Response.Write(satirSayisi + " indeksli verinin Name değeri:" + gelenName);
}

int index = 0;
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
   //Template kolonumuzda satır numaralarını oluşturuyoruz

   GridViewRow gelenSatir = e.Row;

   try
   {
      Label lblIndex = (Label)gelenSatir.Cells[0].FindControl("lblRowIndex");
      lblIndex.Text = index.ToString();
      index++;
   } catch { }
}
DataKeyNames’e değer atarken, kullanmak istediğimiz kolonları virgülle ayırarak belirtebiliyoruz.Böylece birden fazla kolon da DataKeys içerisinde tutulabiliyor.




TemplateField kullanımı

GridView’de visible özelliği false olan kolonlara veri bağlanmadığını biliyoruz.Fakat bu kolon bir TemplateField olursa,içerisine koyacağımız bir kontrolü veriyi elde etmek amacıyla kullanabiliriz.
Öyleyse projemize yeni bir web form ekleyerek, TemplateField kullanımını incelemeye çalışalım.

default4.aspx
<asp:TextBox ID="txtRowIndex" runat="server" />
<asp:Button ID="btnGoruntule" runat="server" Text="Görüntüle" OnClick="btnGoruntule_Click" />

<asp:SqlDataSource ID="dsProduct" runat="server"
   ConnectionString="data source=localhost;database=AdventureWorks;integrated security=SSPI"
   SelectCommand="SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product">
</asp:SqlDataSource>

<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvProducts_RowDataBound">
   <Columns>
      <asp:TemplateField HeaderText="RowIndex">
         <ItemTemplate>
            <asp:Label ID="lblRowIndex" runat="server" />
         </ItemTemplate>
      </asp:TemplateField>
      <asp:TemplateField HeaderText="ProductID" Visible="false"> <%-- ProductID kolonu için bir TemplateField tanımlayıp,visible özelliğine false atıyoruz. --%>
         <ItemTemplate>
            <asp:Label ID="lblProductID" runat="server" Text=’<%# Eval("ProductID") %>’ /> <%-- ProductID kolonundan gelen veriyi, TemplateField’imizin içerisindeki Label’ın Text özelliğine Eval metodu ile  bağlıyoruz--%>
         </ItemTemplate>
      </asp:TemplateField>
      <asp:BoundField HeaderText="Name" DataField="Name" />
      <asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
      <asp:BoundField HeaderText="SellStartDate" DataField="SellStartDate" />
   </Columns>
</asp:GridView>

default4.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
   gvProducts.DataSource = dsProduct;
   gvProducts.DataBind();
}

protected void btnGoruntule_Click(object sender, EventArgs e)
{
   int satirSayisi = Convert.ToInt16(txtRowIndex.Text);

   Label lblProductID =(Label)gvProducts.Rows[satirSayisi].Cells[1].FindControl("lblProductID");
   string gelenDeger = lblProductID.Text;
  
   Response.Write(satirSayisi + " indeksli verinin ProductID değeri:" + gelenDeger);
}

int index = 0;
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
   //Template kolonumuzda satır numaralarını oluşturuyoruz

   GridViewRow gelenSatir = e.Row;

   try
   {
      Label lblIndex = (Label)gelenSatir.Cells[0].FindControl("lblRowIndex");
      lblIndex.Text = index.ToString();
      index++;
   } catch { }
}
Default4.aspx dosyasını çalıştıralım.



Gördüğünüz üzere, TemplateField kolonumuzun içerisindeki Label kontrolümüze erişebiliyoruz ve bunu kolonun gizlenmiş olmasına rağmen yapabiliyoruz. Yalnız burada DataKeyNames özelliğine değer atamadığımız için herhangi bir enkript işlemi gerçekleşmiyor.Bu sebeple, eğer korumak istediğiniz bir veri söz konusuysa DataKeyNames kullanmak gerekir.Doğru bir kod tasarımı için de kullanılması gereken yol budur. Böylece bir makalenin daha sonuna gelmiş bulunuyoruz.Bir dahaki makalede görüşmek üzere,hoşçakalın...

Cenk Özdemir
[email protected]
Makale:
DataGrid ve GridView Kontrollerinde Görünmez Kolonlar ASP.NET Cenk Özdemir
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor