Kategoriler


SON YORUMLAR
mehmet uluğ
bu makalemsi makale! şaka olmalı:)
sevda
beğendim
Reyting Amca
Sitenin reytingi düştü. Google.da aratınca arkalarda çıkıyor. Eskiden ilk sırada çıkardı. Site sahibi ateşli yazılar yazmıyor 1-2 yıldır...
Seda
web sitesi, masa üstü uygulamaları, muhasebe, restaurant, otel, barkot sistemleri yazılımı yapılır. adres:s.sedaerden@gmail.com
Hafize
Yazılım ödevleri ve web sitesi yapılır.Bilgi için hafizearduc@hotmail.com
Gamze
C#, C++, ASP.NET-MVC, HTML-CSS, Matlab, Arduino ödevleri yapılır. Bilgi için; gamze.zirh@gmail.com
Eyüp yılmaz
merve seni seviıyorum asl bebeyoö
BEYZADE BOZTEPE
18 Yaşındayım ınstagram=beyzadebztp
Eyüp yılmaz
39 yasındayım coderım hackerıım ıp verın modemınıze vurayım
BEYZADE BOZTEPE
18 Yaşındayım ınstagram=beyzadebztp (çıkın çıkın gelin GIZLARRRRR)
BEYZADE BOZTEPE
EYVALLAH BENDE İYİYİM
BEYZADE BOZTEPE
İYİYİM GEZEGEN SEN NASILSIN
Eyüp yılmmaz
17 yasındayım kız talıplerımı beklıyom ınsatgram= eyup.yılmaz3
BEYZADE BOZTEPE
MERHABA DÜNYA

Bilgisayar Mühendisleri
Here is the website inspired me to use 
it as a guide when I tried to define 
myself as an engineer candidate a few 
years ago. It really helped me to work
 and study feeling in confidence with 
being on the right way. I suggest this 
website to whom it may direct her/his 
to find the right career path. It 
includes many articles varies from 
real life experiences to detailed 
software engineering issues. But the 
most dignified parts for me are the 
articles in general and career titles.
Son okunan makaleler:
DataGrid ve GridView Kontrollerinde Görünmez Kolonlar
CSS Dersleri - CSS Nedir
ASP.NET - The ArrayList Object
Installing ASP.NET
Staj Yeri Nasıl Bulunur? Staja hazırlık olarak neler yapmalıyım?
ASP.NET ile GIS Uygulamaları
Differences between ASP and ASP.NET
ASP .NET Maintaining the ViewState
Askerlik ve Bilgisayar Mühendisliği
Askerlik ve Bilgisayar Mühendisliği
Bilgisayar mühendisliği öldü?
Bilgisayar Mühendisleri için CV hazırlama rehberi - 3
Bilgisayar mühendisliği öldü?
VNC Nedir? (Virtual Network Computing)
Askerlik ve Bilgisayar Mühendisliği
Askerlik ve Bilgisayar Mühendisliği
En iyi bilgisayar mühendisliği bölümüne sahip üniversiteler
Bilgisayar mühendisliği öldü?
Askerlik ve Bilgisayar Mühendisliği
Bilgisayar mühendisliği öldü?

Bilgisayar Mühendisleri Portalı

DataGrid ve GridView Kontrollerinde Görünmez Kolonlar


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...

Bu makaleyi beğendin mi? Yorumunu Yaz!







Sizden Gelen Yorumlar:

Yorum Yazın

turkiyem(16.04.2015 16:19:10)
Hocam harika anlatmışsınız. Ellerinize sağlık. Sorunumu hallettim anlatım sayesinde.Teşekkürler.
%0 %0 %100
Katılıyorum Çekimserim Katılmıyorum



susam sokağı(27.10.2011 08:53:57)
Teşekkürler, örnekli güzel bir açıklama olmuş. Tahmin ettiğim gibi güvenlik ile ilgili bir sorundan dolayı, gridView kullanılmış :)
%0 %0 %100
Katılıyorum Çekimserim Katılmıyorum






Copyright© 2001-2017. Bilgisayar Mühendisleri Portalı | Bütün hakları saklıdır.