Archive for the ‘ASP.NET’ tag
ASP.NET 4.0 – Kontroller için ClientIDMode Özelliği
ASP.NET de kontroller render edildikten sonra bir ID değeri alıyor ve bu ID değeri tüm kontroller için benzersiz oluyor. Bu yüzden, eğer kontrol UserControl yada MasterPage içerisindeyse kontrol’ün ID’si <I>UserControlAdi_KontrolAdi</I> şeklinde uzun bir isme sahip oluyor. Bu şekilde özellikle istemci taraflı geliştirme yaparkan(Javascript, JQuery vs.) bu kontrollere erişmek çok zor oluyor ve uygulamayı geliştiren kişinin geliştirme süresini uzatıyordu.
ASP.NET 4.0 Öncesi ve Read-Only ClientID Özelliği
Aslında ASP.NET içerisinde her kontrolün ClientID isimli read-only bir propertysi var. Bu property ile kontrolün alacağı ID’ye erişebiliyoruz. Fakat kontrolü bir user control içerisine taşırsak <I>WebUserControl1_lblClientID</I> gibi bir ClientID’ye sahip oluyor. Bu da istemci tarafında yapılan işlemi ve süreci etkiler, yapılan işlemin hatalı olmasına neden olur. Çünkü eğer harici bir dosya içinde İstemci taraflı işlemler yapılıyorsa orada da ilgili değişikliğin yapılması gerekir.
ASP.NET 4.0 Öncesi ClientID Özelliği
Response.Write(KonrolAdi.ClientID);
KonrolAdi.ClientID = “Atanamaz”; // => Read only bir özellik, atama yapılamaz !
</DIV>
ASP.NET 4.0 Yaklaşımı ve ClientIDMode Özelliği
İstemci taraflı geliştirmenin web uygulamalı içerisinde kullanımın artmasıyla birlikte bu sorunu aşmak için ASP.NET 4.0 ile birlikte kontrollere ClientIDMode isimli bir özellik eklendi. Bu özellik kontrol render edildikten sonra kontrolün alacağı ClientID değerinin istediğimiz gibi atanmasını sağlıyor. Yani ClientID’nin değeri eskiden olduğu gibi uzunca bir değer olabilir, bizim vereceğimiz her hangi bir değer olabilir ya da kontrol’ün ID’si ile aynı olabilir.
ClientIDMode özelliğinin alabileceği 4 özellik var. Bunlar Legacy (varsayılan değer), Inherit, Static, Predictable.
Legacy
ClientIDMode’un default değeridir. Eğer ClientIDMode özelliğine Legacy’i enum’u set edilmişse kontrolün alacağı ID değeri önceki sürümlerde olduğu gibidir. Yani uzunca bir ClientID oluşur
Örnek Kullanımı
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Label ID="lblSample" ClientID="lblSample" ClientIDMode="Legacy" runat="server" Text="Deneme"></asp:Label>
</asp:Content>
Html Çıktısı
<span id="ctl00ctl00_ContentPlaceHolder1_lblSample">Deneme</span>
</DIV>
Inherit
Her kontrol için default davranış gösterir. İçerisinde yer aldığı parent kontrolün ClientIDMode property’si ne olarak belirlenmişse, kontrol içinde o özellik atanır. Örneğin bir MasterPage ve Content sayfası var. Content sayfanın içinde de bir Label var. Master Page içerisindeki ContentPlaceHolder’ın ClientIDMode özelliği static ise Content sayfa içerisinde yer alan kontrolün özelliği de static olarak belirlenir.
Örnek Kullanımı
Master Page
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" ClientIDMode="Static"> </asp:ContentPlaceHolder>
Content
<asp:Label ID=" lblSample" ClientID="lblInheritSample" ClientIDMode="Inherit" runat="server" Text="Deneme"></asp:Label>
Html Çıktısı
<span id="lblInheritSample">Deneme</span> // Parent Kontrolün(Content) ClientIDMode özelliği static olduğu için içteki kontrolünde ClientIDMode özelliği static olarak atandı…
</DIV>
Static
Bu mod seçildiğinde, kontrolün ClientID’ne ne atamışsak oluşacak olan HTML çıktısına da o değer atanır. Burada dikkat edilmesi gereken şey, ClientID’nin benzersiz olduğundan emin olmak zorundayız. Yani elimizde 2 User Control var. Her ikisi içinde de bir label olduğunu düşünürsek iki label’ın CleintID’si farklı olması gerekir. Eğer ikisi de aynı olursa, client site de yapacağımız işlemler de yanlış sonuçlar alabiliriz. Özellikle de databound kontrollerinden kullanmamak gerekir.
Örnek Kullanımı
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Label ID=" lblSample" ClientID=”lblClientSample" ClientIDMode="Static" runat="server" Text="Deneme"></asp:Label>
</asp:Content>
Html Çıktısı
<span id=" lblClientSample">Deneme</span>
</DIV>
Predictable
Bu özellik, Gridview, Repeater gibi DataBound kontroller için daha kullanışlıdır. Burada işe yarayacak bir diğer property de RowClientIDSuffixözelliğidir. Bu özellik ile DataBound kontrolünün kolonu içerisinde yer alan kontrolün ClientID’nin değerinin sonuna takı olarak belirttiğimiz alanın değeri eklenir.
Örnek Kullanımı
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" ClientIDMode="Predictable" RowClientIDSuffix="UrunAdi"> // RowClientIDSuffix özelliğine veri kaynağından gelen bir alan yazmak zorundayız. Birden fazla kontrol için yapacaksak alanları virgül ile ayırabiliriz.
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblUrunAdi" runat="server" Text=’<%# Eval("UrunAdi") %>’></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Html Çıktısı
<table cellspacing="0" rules="all" border="1" id="ctl00_ContentPlaceHolder1_GridView1" style="border-collapse:collapse;">
<tr><th scope="col"> </th></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_lblUrunAdi_Kalem">Kalem</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_lblUrunAdi_Defter">Defter</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_lblUrunAdi_Silgi">Silgi</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_lblUrunAdi_Dosya Kağıdı">Dosya Kağıdı</span>
</td></tr>
</table>
Eğer ClientIDMode özelliğini Predictable yapmasaydık,
<table cellspacing="0" rules="all" border="1" id="ctl00_ContentPlaceHolder1_GridView1" style="border-collapse:collapse;">
<tr><th scope="col"> </th></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_ctl02_lblUrunAdi">Kalem</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_ctl03_lblUrunAdi">Defter</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_ctl04_lblUrunAdi">Silgi</span>
</td></tr><tr><td>
<span id="ctl00_ContentPlaceHolder1_GridView1_ctl05_lblUrunAdi">Dosya Kağıdı</span>
</td></tr>
</table>
</DIV>
Makalenin sonuna geldik, başka bir makalede görüşmek üzere. ASP.NET ile kalın
Sem GÖKSU
www.semgoksu.com | www.yazilimgunlugu.com
sem.goksu@yazilimgunlugu.com
Kaynaklar
msdn.com
ASP.NET 4.0 Caching – Data Caching
İlk makalemiz de performansı arttırmak için Output Caching ile sayfanın çıktısını önbelleğe almıştık. Output Caching ile sayfa çıktısının tamamını yada belli bir kısmını önbellekleyebiliyorduk. Fakat her zaman bu yeterli olmayacaktır. Bazı durumlar da sayfa içerisinde kullanılan verinin yada verilen de önbelleklenmesi gerekebilir. Bu durumda Output Caching kullanamayız, çünkü Output Caching ile sadece sayfanın çıktısını önbellekleyebiliyoruz. Uygulamamız içerisinde veri yada verileri önbelleğe alabilmek için Data Caching’i kullanmamız gerekiyor.
Output Caching’de bahsettiğimiz durum Data Caching içinde geçerlidir. İstenilen bilginin tekrar tekrar kaynaklardan çekilmesi yerine, gelen ilk istek server tarafından karşılanacak (veritabanı yada başka bir sağlayıcı da olabilir) sonrasında ise önbelleklenen veri bellekten alınıp uygulama içerisinde kullanılacak. Veritabanından aldığımızı düşünürsek bu işlem performans için çok önemli bir artış sağlıyor olacaktır.
Yukarıdaki örnek, önbelleklenen ve önbelleklenmeyen bir database işleminin akış şemasını gösteriyor. İlk örnekte gelen her istek ilgili Query’i çalıştırmak için database’e bağlanıyor, hem server tarafında trafik oluyor hem de verinin databaseden getirilmesi sırasında performans kaybı yaşanıyor. İkinci örnekte ise sadece ilk seferde veritabanına bağlanıyor ve veriyi önbelleğe atıyor. Sonrasında gelen tüm talepler önbellekten getiriyor. Bu da verinin hazır bir şekilde alınmasını, dolayısıyla uygulamanın daha performanslı çalışmasını sağlıyor.
En basit kullanım şekli ile bir nesneyi Cache’e atmak aşağıdaki gibidir…
Cache.Insert(“Key”, Data);</DIV>
Cache’e attığımız nesneyi silmek istiyorsak da aşağıdaki gibi bir kullanıma ihtiyacımız var.
Cache.Remove(“Key”);</DIV>
Data caching için kullanabileceğimiz 3 yöntem var. Absolute Time, Sliding Time(Süreye Bağlı Önbellekleme) ve File Dependency (Dosya Değişimine göre Önbellekleme).
Absolute Time
Belirtilen süre boyunca data önbellekte saklanır bu süre içerisinde gelen talepler önbellekten karşılanır. Sürenin sonunda ise data önbellekten silinecektir.
Cache.Insert(“key”, data, null, DateTime.Now.AddMinutes(1), System.Web.Caching.Cache.NoSlidingExpiration);</DIV>
İlk parametre, önbelleğe alınan veriye ulaşabilmemiz için ulaşacağımız key, ikinci parametre önbellekte saklanacak olan verinin kendisi, üçüncü parametre CacheDependency nesnesi (biz burada bunu şimdilik kullanmayacağımızı için null gönderiyoruz), dördüncü parametre verinin ne kadar süre önbellekte kalacağını belirten DateTime tipinde bir değer, son parametre de TimeSpan tipinde bir değer istiyor, Absolute Time için, parametre olarak Cache sınıfında bulunan NoSlidingExpiration fielad’ını parametre olarak gönderiyoruz.
Sliding Time
Belirtilen süre boyunca data önbellekte saklanır. Eğer bu süre içerisinde yeni bir talep gelirse süre yeni baştan başlar. Sürenin sonunda ise veri önbellekten silinir.
Cache.Insert(“key”, Data, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(120));</DIV>
Absolute time da olduğu, Sliding Time içinde ilk üç parametre aynı. Dördüncü parametre hatırlarsak bizden DateTime tipinde bir parametre istiyordu. Sliding Time’a göre önbellekleme yapacaksak, Cache sınıfında bulunan NoAbsoluteExpiration fieldını parametre olarak yolluyoruz, son parametreye de timespan tipinde bir değer yolluyoruz.
File Dependency
Disk üzerinde yer alan bir dosyadan çekilen verinin içeriği değişene kadar önbellekleme yapılır.
[XML]
<?xml version=”1.0″ encoding=”utf-8″?>
<Products>
<Product>
<ProductID>1</ProductID>
<Name>Masa</Name>
</Product>
<Product>
<ProductID>2</ProductID>
<Name>Sandalye</Name>
</Product>
<Product>
<ProductID>3</ProductID>
<Name>Dolap</Name>
</Product>
</Products></DIV>
[C#]
CacheDependencydep = new CacheDependency(Server.MapPath(“Data.xml”));
//XML’en gelen verinin data isimli bir objeye atıldığı varsayılmıştır…
Cache.Insert(“key”, data, dep, DateTime.Now.AddHours(2), System.Web.Caching.Cache.NoSlidingExpiration);
</DIV>
İki saat boyunca önbelleğe alınır ancak, dosyada herhangi bir değişiklik olursa önbelleklenen veri silinir.
Örnek
Öğrenci koleksiyonu içerisinde yer alan veriyi 30 dakika boyunca önbellekten getirelim. Bunun için ilk olarak Ogrenci isimli bir nesne oluşturalım. Aynı nesne içerisinde öğrencileri getirecek öğrenci listesi de yer alacak.
[Ogrenci.cs]
classOgrenci
{
public static List<Ogrenci> Ogrenciler()
{
// Veriyi database’den de getirebilirsiniz… Sadece örnek olması için bu şekilde yaptık.
return new List<Ogrenci>()
{
new Ogrenci(){ OgrenciID = 1, AdSoyad = “Sem Göksu”},
new Ogrenci(){ OgrenciID = 2, AdSoyad = “Elçin Göksu”},
new Ogrenci(){ OgrenciID = 3, AdSoyad = “Ercan Kilercioğlu” }
};
}
public int OgrenciID { get; set; }
public string AdSoyad { get; set; }
}</DIV>
Şimdi sayfamızın Page_Load eventine gidelim.
[Page_Load]
List<Ogrenci> Ogrenciler = null;
if(Cache["Ogrenciler"] != null)
{
Ogrenciler = Cache["Ogrenciler"] as List<Ogrenci>;
Response.Write(“Veri Cache’den getirildi…”);
}
else
{
Ogrenciler = Ogrenci.Ogrenciler();
Cache.Insert(“Ogrenciler”, Ogrenciler, null, DateTime.Now.AddMinutes(30), System.Web.Caching.Cache.NoSlidingExpiration); // Absolute Time Caching
Response.Write(“Veri Veri Kaynağından Getirildi…”);
}
GridView1.DataSource = Ogrenciler;
GridView1.DataBind();
</DIV>
Testimizi yapalım…
| Sayfayı çalıştıralım, | İkinci kez çalıştıralım, |
Makalenin sonuna geldik, başka bir makalede görüşmek üzere…
Sem GÖKSU
www.semgoksu.com | www.yazilimgunlugu.com
sem.goksu@yazilimgunlugu.com
Kaynaklar
asp.net
ASP.NET 4.0 Caching – Output Caching
Web uygulamaları geliştirirken en önemli konulardan bir tanesi performanstır. ASP.NET ile web uygulaması geliştirirken yapılan uygulamanın daha performanslı çalışması için Caching(Önbellekleme) Mekanizması kullanılır. Caching ile sayfanın HTML çıktısının tamamı yada belli bir kısmı bellekte saklanır. Böylece HTML derlenip, tekrar tekrar oluşturulmak yerine bellekten alınarak kullanıcıya iletilir. Bu sayede hem serverdaki trafik azalır hem de gelen isteğin değerlendirilip HTML’in yeniden üretilmesi sırasında kaybedilen zaman kazanılmış olur.
HTML çıktısının tamamını önbellekleyebileceğimiz gibi belli bir kısmını da önbellekleyebiliriz. Önbelleklediğimiz bir alan içerisinde de belli bir alanı dinamik hale getirebiliriz. İlk olarak sayfa çıktısının tamamının nasıl önbellekleneceğine bakalım.
Output Caching (HTML çıktısının önbelleklenmesi)
Output Caching ile sayfanın tamamının belli bir süre içerisinde önbelleklenmesini sağlayabiliriz. Böylece sayfa önbelleğe alındıktan sonra bir sonraki ziyarette HTML önbellekten alınarak kullanıcıya gösterilecek. (Bir sonraki ziyaretin de önbellekleme süresi içerisinde olması gerekiyor)
Sayfayı önbelleklenebilmesi için sayfamıza OutputCache direktifini(Directive) eklememiz gerekiyor. Örnek kullanım;
<%@OutputCache Duration=”300″ Location=”Any” VaryByParam=”none” %></DIV>
Burada ilk göze çarpan Duration ve Location özellikleridir. Duration özelliği saniye cinsinden sayfanın cache’de ne kadar tutulacağına belirliyor. Location özelliği de sayfanın nerede önbellekleneceğini belirten bir enum sunuyor, bu enumun varsayılan değeri Any’dir.
OutputCacheLocation Enum’unun alabileceği değeler
Any
Önbellekleme, isteği yapan Client, Proxy Server yada isteğin yapıldığı server üzerinde olur.
Client
Önbellekleme, isteği yapan Client’ de olur.
DownStream
Önbellekleme, isteği yapan Client’de ve Proxy Server üzerinde olur.
None
Önbellekleme yapılmaz.
Server
Önbellekleme, isteğin yapıldığı Server üzerinde olur.
ServerAndClient
Önbellekleme, isteği yapan Client’de ya da isteğin yapıldığı Server üzerinde olur.</DIV>
Şimdi bir ASP.NET sayfası açalım. Sayfa direktiflerine OutputCache direktifini ekleyelim. Sayfamız 300 saniye boyunca önbelleklenecek.
<%@OutputCache Duration=”300″ Location=”Any” VaryByParam=”none” %></DIV>
Sayfanın Page_Load eventine de aşağıdaki kodu yazalım.
protectedvoid Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
}</DIV>
Sayfa çalıştığında ilk istek değerlendirilecek ve o anki tarih ve saat bilgisi ekrana gelecek. Bundan sonra yapılacak istekler de 300 saniye boyunca önbelleklenmiş veri ekrana gelecek. 300 saniye sonunda da yeni tarih ve saat ekranda gösterilecek.
| İlk İstek | 300 Sn içindeki istekler | 300 Sn Sonra |
| 2009-02-18 12:21:00 | 2009-02-18 12:21:00 | 2009-02-18 12:26:00 |
Bu şekilde çıktıyı önbelleğe aldık, peki ya sayfamıza QueryString’den gelen değerlere göre farklı bilgi içeriyorsa ne olacak? İşte bu durumda her QueryString anahtarı için ayrı ayrı çıktıların önbelleklenmesi sağlayan VaryByParam özelliğini kullanıyoruz.
<%@OutputCache Duration=”300″ Location=”Any” VaryByParam=”KategoriID” %></DIV>
QueryString’den gelen KategoriID anahtarının değerine göre önbellekleme yapılır.
<%@OutputCache Duration=”300″ Location=”Any” VaryByParam=”KategoriID,Dil” %></DIV>
QueryString’den gelen KategoriID ve Dil anahtarlarının değerlerine göre önbellekleme yapılır.
<%@OutputCache Duration=”300″ Location=”Any” VaryByParam=”*” %></DIV>
QueryString’den gelen tüm anahtarların değerine göre ayrı ayrı önbellekleme yapılır.
Fragment Caching(Belli bir kısmının önbelleklenmesi)
Sayfanın tamamı yerine sadece belli bir kısmının da güncellenmesini sağlayabiliyoruz demiştik. Örneğin bir haber sitemiz var. Ana sayfasında da anlık değişebilecek bölümler vardır. Fakat bazı bölümler de sabittir. İşte biz sadece sabit olan bölümleri önbelleğe almak istiyorsak bunun için Fragment Caching’i kullanmalıyız. Bunun için de bu bölümler için User Control yapıp, oluşturduğumuz User Control içerisinde önbellekleme işlemi yapacağız.
Şimdi bir User Control oluşturup, onu yeni bir sayfaya ekleyelim. UserControl içine de bir label ekleyelim. Son olarak da UserControl’ün direktiflerine OutputCache direktifini ekleyelim.
MyUserControl.ascx
<%@Control Language=”C#” AutoEventWireup=”true” CodeFile=”MyUserControl.ascx.cs” Inherits=” MyUserControl ” %>
<%@OutputCache Duration=”300″ VaryByParam=”none” Shared=”true”%>
<asp:LabelID=”Label1″ runat=”server” Text=”Label”></asp:Label></DIV>
Kod tarafında da o anki tarih ve saati Label’a atayalım.
MyUserControl.ascx.cs
protectedvoid Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTimeTime.Now.ToString();
}</DIV>
Şimdi UserControl’ü ekleyeceğimiz ASP.NET sayfasına geçelim. Bir label ekleyelim ve Page_Load eventin de o anki tarih ve saati label’a atayalım.
FragmentPage.aspx.cs
protectedvoid Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}</DIV>
Sayfaya gelen talepleri ve ekran dan çıkan saat bilgilerini inceleyelim.
| İlk İstek | 300 Sn içindeki istekler | 300 Sn Sonra | |
| Page | 2009-02-18 12:21:00 | 2009-02-18 12:22:01(Örneğin) | 2009-02-18 12:26:00 |
| UserControl | 2009-02-18 12:21:00 | 2009-02-18 12:21:00 | 2009-02-18 12:26:00 |
Yukarıdaki tabloda da görüldüğü gibi Page.aspx’ gelen tüm istekler önbellekleme yapılmadan kullanıcıya aktarılıyor. UserControl içinde ise ilk istek sonrasında 300 saniye boyunca önbellekteki veri kullanıcıya gösteriliyor. Önbellekleme süresi sona erdikten sonra da yeni çıktı oluşturuluyor.
UserControl nerelerde kullanılmışsa kullanıldığı her yer için ayrı ayrı çıktısı bellekte saklanır. Shared özelliğini True yaparak, tüm sayfalar için tek bir çıktı bellekte saklanır.
Substitution Caching(Önbelleklenen alanın dinamik hale getirilmesi)
Bazı durumlarda önbelleklenen bir sayfanın belli bir kısmının dinamik hale getirilmesi gerekir. Bunu yapabilmek için de Substitution Caching’i kullanıyoruz.
Önbellekleme yapılmış bir sayfa içinde dinamik alan oluşturabilmek HTML tarafında Substitution kontrolünü yada HttpResponse sınıfınınWriteSubSubstitution metodunu kullanmak zorundayız. Her ikisi de bizden, parametre olarak HttpContext sınıfını alan, geriye string döndüren static bir metot bekliyor.
Öncelikle Page_Load’da tarih ve saati ekrana yazdıralım, sonrasında ise Static olacak Tarih metodumuzu yazalım.
protectedvoid Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
} protectedstatic string Tarih(HttpContext context)
{
returnDateTime.Now.ToString();
}</DIV>
Şimdi HTML tarafında önbelleklenecek ve dinamik olacak alanımızı belirleyelim.
<%@Page Language=”C#” AutoEventWireup=”true” CodeFile=”SubstitutionCaching.aspx.cs” Inherits=”SubstitionCaching” %>
// Sayfa 300 saniye boyunca önbelleklenecek…
<%@OutputCache Duration=”300″ VaryByParam=”none” %>
<!DOCTYPEhtml PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<htmlxmlns=”http://www.w3.org/1999/xhtml”>
<headrunat=”server”>
<title>Substitution Caching</title>
</head>
<body>
<formid=”form1″ runat=”server”>
<div>
// Dinamik olacak alan, Substitution kontrolü dinamik içerik oluşturabilmek için static bir metot bekliyor. Bekleyen özelliği de MethodName’dir.
<asp:Substitution ID=”Substitution1″ runat=”server” MethodName=”Tarih”/>
// Yada
<%Response.WriteSubstitution(new HttpResponseSubstitutionCallback(Tarih)); %>
</div>
</form>
</body>
</html>
</DIV>
Şimdi de önbelleklenen ve dinamik hale getirilen alanların değerlerine bakalım.
| İlk İstek | 300 Sn içindeki istekler | 300 Sn Sonra | |
| Page | 2009-02-18 12:21:00 | 2009-02-18 12:22:00 | 2009-02-18 12:26:00 |
| DinamikAlan | 2009-02-18 12:21:00 | 2009-02-18 12:21:01(Örneğin) | 2009-02-18 12:26:00 |
Caching mekanizmasını kullanarak sayfalarımızın daha performanslı çalışmasını sağladık JMakalenin sonuna geldik, başka bir makalede görüşmek üzere…
Sem GÖKSU
www.semgoksu.com | www.yazilimgunlugu.com
sem.goksu@yazilimgunlugu.com
Kaynaklar
msdn.com
Asp.net Application Profiling
Birçoğumuzun gözden kaçırdığı, kaçırmasa da yapmayı ötelediği işlemlerdendir çalışan sistemin izlenmesi analiz edilmesi. Yazılmış kodların ya da çalışır bir sistemin profile edilmesi hızlı gelişen süreçler dahilinde lüks olarak nitelense de ayrılacak kısa süreler umulmadık çözümlere ulaştırabilir problemleri, gereksinimleri.
İşte bu gereksinimlerin öneminden yola çıkarak Profiling ve Monitoring araçlarını incelemeye çalışacağım kısa kısa.
İlk incelemek istediğim araç AutomatedQA adlı bir firmaya ait olan AQtime adlı bir uygulama. Performans
üzerine ürünler geliştiren bu firmanın AQtime ürününde hedeflenen performansa etki eden işlemleri izlemek ve memory kullanımını debug etmek. Ayrı olarak kullanılabildiği gibi Visual Studio içinden de kullanmak mümkündür. Deneme sürümünde her visual studio başlangıcında deneme sürümü confirmasyonu alması bir süre can sıkıcı gelebilir.
Native code için profile ve debug imkanı da veren bu uygulamada yapılandırmamızı asp.net uygulaması için yapıyor olacağız.
Asp.Net uygulamamızı Visual Studio 2005\2008 içerisinde açtıktan sonra proje özelliklerinden Build menüsü yardımıyla Debug işlemleri için Optimize Code seçeneğinin seçili olmadığından emin olalım. Bu seçimden emin olduktan sonra projeyi tekrar compile edelim.
Test edebilmek amacıyla basit birkaç for döngüsü kullanacağım bir web application oluşturdum. Bu web application in öncelikle iis e application olarak tanımlamamız ve virtual bir path vermemiz gerekli.
Test uygulamasıyla ilgili IIS yapılandırmasından sonra AQTime yapısına baktığımızda New Project seçeneğiyle yeni bir profiler projesi başlatıyoruz. Açılan bu projeyi IIS teki test sitemizle konuşturmak için bin folderı altındaki web uygulaması için assembly dll’ ini sol navigasyon menüsündeki Add Module seçeneğiyle projeye ekliyoruz.
Öncelikle test etmek ve izlemek istediğimiz uygulama Asp.Net uygulaması olduğu için Asp.Net modunu seçiyoruz. ![]()
Profile etmek istediğimiz aşamaları area alanından seçerek profiling işlemini başlatıyoruz. (Ingilizce bir kelimeye etmek fiili ekleyerek türkçeleştirmek en sevmediğim kullanımlardan biridir aslında ama profiling türkçe olarak daha mantıklı bir şekilde çeviremedim)
Run dedikten sonra karşınıza bir pencere daha çıkacaktır ve bu pencereden hangi işlemleri Runtime işlemlerini mi sonrasını mı vs izleme aşamalarını seçebilirsiniz.
![]()
Bu seçimi de yaptıktan sonra ayarların tamam olduğunu ve IIS uygulamasının başlatılmasının beklendiğini gösteren bir uyari göreceksiniz. Bu uyarıyla birlikte IIS uygulamasını Internet Explorerdan çağırmak AQtime ı aktif etmek ve izleme işlemine başlamak için yeterli.
Profiling esnasında uygulamanızda neler olup bittiğini hangi modullerin kaç saniyede ayaklandırıldığını sistemin nerelere eriştiğini erişemediğini monitor penceresinden izleyebilirsiniz.
Proje süreçlerinde zaman alması bakımından çokta üzerinde durulmaya ama zaman zaman harcanan zamanı kat kat fazlasını kazandıran işlemler olan Profiling ve Performans aşamalarındaki araçları incelemeye devam edeceğim.
CrystalReports Export \ Export* uygulamasına farklı bir çözüm
Crystal Reports raporlama konusunda oldukça sık kullanılan bir üründür. Kolay geliştirilebilir olması ve veritabanıyla olan ilişkisinin kolay kurgulanabilir olması sık kullanılmasında en önemli etkenlerdendir.
DataSet ve DataTable yapılarıyla oluşturacağınız ReportDocument formatıyla istediğiniz formatta çıktı almanız mümkündür.
Export fonksiyonunu ek olarak ekleyeceginiz ExportOptions özellikleriyle kullanmanız gereklidir. Diğer özelliklerde Export özelliğinin daha spesifik versiyonlari olarak düşünülebilir.
ReportDocument rd = obj.MReportDocument;
ExportOptions options = new ExportOptions();
PdfRtfWordFormatOptions pdf = new PdfRtfWordFormatOptions();
DiskFileDestinationOptions destination = new DiskFileDestinationOptions();
destination.DiskFileName = @"c:\1.pdf";options.ExportDestinationType = ExportDestinationType.DiskFile;
options.ExportDestinationOptions = destination;
options.ExportFormatOptions = pdf;
options.ExportFormatType = ExportFormatType.PortableDocFormat;rd.Export(options);
Bu genel bilgilerin yanında esas olark yaşanabilecek bir raporlama sorununu ve bulduğum javascript destekli çözümü paylaşmak istiyorum.
Öncelikle sorunu belirtmek gerekirse iki tane raporun aynı anda pdf olarak bir aspx sayfasında Response edilmesidir. Sıkça karşılabileceğiniz üzere bir sayfada birden fazla rapor çıktısı istenebilir. Diğer bir deyişle, kullanıcının download etmeye zorlanması istenebilir. Ancak durumu ilginç kılan
ReportDocument.ExportToHttpResponse özelliğinin ilk response tan sonra bitirme işlemi yaparak Response u sonlandırmasıdır.
Bu sıkıntıyı aşmak için Crystal Reports dahil birçok ortamda cevap aramama karşın herhangi bir öneri bulamadım. Sorunu yaşayan çok fakat çözüm bulan hiç yoktu.
Bunun için ReportDocumentlerimi elde ettiğim sayfada her iki dokumanı da Current Cache ‘e yazdırdım.
ReportDocument rd =obj.MReportDocument;
HttpContext.Current.Application["asd"] = rd as object;
Daha sonra işlemi sadece raporu response edip yazdırmak olan boş bir aspx sayfası oluşturdum. (OpenReport.aspx)
Bu sayfanın içeriğinde Page Load aşamasını
ReportDocument rd = null;
if (HttpContext.Current.Application["asd"] != null)
rd = HttpContext.Current.Application["asd"] as ReportDocument;if (rd != null)
rd.ExportToHttpResponse(ExportFormatType.PortableDocFormat, HttpContext.Current.Response, true, "Report_" + DateTime.Today);
şeklinde düzenledim.
ReportDocumentlerimi cache e yazdığım ana sayfamda;
string url = "OpenReport.aspx?page=1";
string url1 = "OpenReport.aspx?page=2";Page.ClientScript.RegisterStartupScript(this.GetType(), "newWindow", string.Format("<script>window.open(‘{0}’);window.open(‘{1}’);</script>", url, url1));
Kod satırıyla işlem sonlandığında code behinddan çağırılacak olan scriptimi register ettim.
Açılan rapor sayfasında bir diğer seçenek olarak raporu stream olarak header ‘a da yazdırabilirsiniz. ExportToStream kullanacapımız bu yola başvurmamızın farkı dosyayı kaydettirmek yerine sayfa içinde gömülü olarak gelmesini istemektir;
MemoryStream stream = null;
ReportDocument rd = null;
if (HttpContext.Current.Application["asd"] != null)
rd = HttpContext.Current.Application["asd"] as ReportDocument;if (rd != null)
{
stream = (MemoryStream)rd.ExportToStream(ExportFormatType.PortableDocFormat);
}Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(stream.ToArray());
Response.End();
Özetlediğimizde;
- Ana sayfamda oluşturduğum iki ayrı rapor dosyasını Response a export etmek yerie cache e yazdım.
- Cache e yazma işleminden sonra popupta raporları açacak dosyamı register ettim.
- Açılan sayfada raporları export ederek her bir rapor için ayrı response nesnesi kullanmış oldum.
Umarım bu karışık ama çözüme giden yol bir gün işinize yarar.
Interfacelerle Rol Vermek
Interfaceler desktop uygulamalarında olduğu gibi web uygulamalarında ve com+ uygulamalarında da sıkça kullanılan ve oldukça fayda sağlayan yapılardır. Interface kavramıyla türettiğimiz nesnelere bir yol haritası çizmiş olduğumuzu söyleyebiliriz. Bir programlama dilini bir objeyi ya da daha basit olarak örneklersek bir cihazı kullandığımızda kullanım rehberine bakar özelliklerini inceler ve o nesneyle\cihazla neler yapabileceğimizi anlarız. Interfaceleri bu görevi üstlenmiş yapılar olarak görüyorum. Interfacelere dağıtlmış rollerle elimizdeki sınıflara neler yapabileceklerini bildirmiş olabiliriz.
Bu farkı anlatabilmek için kurguladığım yapıda bir interfacede matematiksel işlemleri bir interfacede metin işlemlerini tanıtarak daha sonra bu interfaceler yardımıyla nesnemin sınırlarını belirlemeyi planlıyorum.
Ayrıca interfaceler haricinde bir de base class tanımlayarak biçebileceğimiz roller haricindeki fonksiyonları tanımlayacağım aşamayı planlıyorum. Burada örnek olarak mesaj gösterimi yapacak olan alert gibi genel bir fonksiyon belirleyerek tanımladım.
Elimizdeki interfacelerle FunctionHelper imizi oluşturarak bu yapı dahilinde neler yapılabileceğini, en başta da söylediğimiz üzere hangi roller üstlenebileceğini belirleyeceğiz.
Helper ıma öncelikle matematik fonksiyonlarını eklemeyek istiyorum ve sadece matematiksel işlemleri yapmak istediğimi belirtiyorum. Implementetion ları yaptıktan sonra gelen fonksiyonları incelediğimizde “throw new NotImplementedException();” la birlikte tanımlandığını görüyoruz. Buradaki önemli nokta interfacelerle biçilen bu rollerin içini bizim doldurmamız gerektiğidir. Snopsisler tamamen bize ait.
Bu tanımlamaları yaptıktan sonra helperımızın çağrıldığı aşamaya bakacak olursak matematiksel fonksiyonların dahil edilmiş olduğunu görebiliriz.
Aynı şekilde interface tanımını metinsel fonksiyonlarımız içinde yaparsak matematiksel fonksiyonlar yanında onları da listeleyebiliriz.
Class tanımıyla eklenecek rollerin farkını göstermek açısından tanımladığım basefunctions katmanını da base olarak eklediğimde alert fonksiyonunun da helper yapıma eklendiğini göreceğiz.
Interfaceten farklı olarak biçtiğimiz bu rolde ayrıca fonksiyon işlemleri tanımlamamıza gerek olmayacaktır. Eklenen fonksiyon dahilindeki işlemler ait olduğu sınıktaki gibi tamamiyle sistemimize dahil edilecektir.
AspxGridview ve Globalization
AspxGridView dahilindeki Edit formlarda Buttonların yerini değiştirmek için ASPxGridViewTemplateReplacement yapısı önerilmekte ve kullanılmaktadır.
Örneğin :
<dxwgv:ASPxGridViewTemplateReplacement ID="UpdateButton" ReplacementType="EditFormUpdateButton" runat="server" />
Fakat bu şekilde bir kullanımda culturelarla birlikte çalışabilmek mümkün değildir. Kullandığınız bir culture yapısı mevcutsa TemplateReplacement içerisinde çalışmadığını gözlemleyebilirsiniz.
GridView için edit form captionlarına runtime’dan erişim, karşılaşabileceğiniz bu prolemi ortadan kaldırmak için önerilen ve kullanılan bir kavramdır.
Ayrıca DevXpress in de önerdiği üzere AspxGridView kendine has resource file mekanızması da kullanılabilir. (DevExpress_Web_ASPxGridView_vX_Y.resx)
Fakat bu da birden farkli resource dosyası kullanımını ve dağınıklığı getireceği için çok kullanışlı bir yapı değildir
.
Yandaki ekran görüntüsünden de görüleceği üzere AspxGridView’da en kullanışlı ve kolay yapı olarak mevcut resource dosyaları kullanılımı önerilebilir;
<SettingsText CommandCancel="<%$ Resources:SiteLabels, resourceLabel1 %>" CommandUpdate="<%$ Resources:SiteLabels, resourceLabel2 %>" />
şeklinde bir yapıyla gridview edit form yapısındaki butonların metinlerini değiştirmek mümkündür.
Burada dikkat edilmesi gereken;
Thread.CurrentThread.CurrentCulture = new CultureInfo(Culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Culture);
değerleriyle geçerli culture i set etmektir.
ASP.Net Samples – Part III: System.Net.Mail with ASP.Net
5 – System.Net.Mail ile Mail Send
Merhaba arkadaslar, bugun sizlere ASP.Net uzerinden Mail gonderme islemi uzerine ornek yapacagiz. Gunumuzde E-Mail yapisi bilmeyen pek az insan vardir sanirim. E-Mail, dunya capinda Bireysel ve Kurumsal olarak kullanilan bir yapidir. Bireysel kullanimlara ornek vermek istersek eger cok yaygin olan mail servislerinden ornek verebiliriz (gmail,hotmail,yahoo gibi). Kurumsal kullanimlarda genelde Microsoft Exchange Server tercih edilir. Exchange serverdan bahsetmek isterdim ama off topic olmamak adina bahsetmesem iyi olur. Gelelim mail gonderme islemini kendi yarattigimiz bir .aspx veya Windows Application uzerinden yapmaya. 2 yapi arasinda pek bir fark oldugu soylenemez acikcasi. Oncelikle bu islemi yapabilmek icin sahip oldugunuz mail adresinizi bir takim bilgilerine ihtiyac duyarsiniz. SMTP, Incoming – Outgoing adresleri gibi. Kendinize ozel bir isim hakki ve domaininiz var ise bu is daha kolay tabi. Ornek vermek gerekirse sahip oldugum www.serkanhekimoglu.com ismi, ve barindirdigim serverimin saglamis oldugu avantajlar dogrultusunda kendi alan adim uzantisinda mail adresi olusturabiliyor. (serkan@serkanhekimoglu.com) gibi. Incoming ve Outgoing bilgilerimde haliyle mail.serkanhekimoglu.com oluyor. Gelelim simdi bunu form uzerinde nasil yapacagimiza.
Isleme baslamak icin bir adet .aspx sayfasi olusturalim, ve .Net’in mail gonderme yapisini kullanabilmek icin gerekli referanslari ekleyelim :
using System.Net.Mail;
using System.Net;
Mail gonderim sirasinda ki islemi basitce dusunecek olursak eger, Mesajimiz, gonderen, alici, konu, ve ana mesajdan olusur. Bunlara ek olarakdan CC, BCC, veya Attachment gibi olaylarda mevcuttur. Dolayisiyla bu degerleri cekebilecegimiz textBoxlari .aspx sayfamiza ekleyelim. Ve gelen kod kismina:
MailAddress From = new MailAddress(txtEmailAddress.Text.ToString(),
txtName.Text.ToString() + " " +
txtSurname.Text.ToString());
MailAddress To = new MailAddress("serkan@serkanhekimoglu.com");
MailMessage Email = new MailMessage(From, To);
Email.IsBodyHtml = true;
Email.Subject = "Message From Serkanhekimoglu.com";
Email.Body = txtMessage.Text.ToString();
SmtpClient MailClient = new SmtpClient();
MailClient.Host = "mail.serkanhekimoglu.com";
MailClient.UseDefaultCredentials = false;
MailClient.Credentials = new
NetworkCredential("serkan@serkanhekimoglu.com", "MAILSIFRENIZ"); MailClient.Port = 26; MailClient.Send(Email);
MailAddress’i biraz kurcalayacak olursaniz CC ve BCC gibi ozellikleride gorebilirsiniz. Burda sorun yaratabilecek tek sey Mail’in cikis port’u olabilir. Default port kullanilir veya manuel olarak cikis portu belirtilebilir. To kismini ister textbox’tan okursunuz ister kendiniz default bir mail adresi set edersiniz. (sekildeki gibi)
ASP.Net Samples – Part II: File Upload, and Forms Authentication
3- File Upload
Merhaba arkadaslar, ASP.NET Samples konusu uzerine devam eden makalemizde bugun son derece basit ama kullanisli olan File Upload uzerine ornek yapacagim. File Upload uzerine aciklama yapilmasi pekte gerekli degildir aslinda, cunku adindana anlasilacagi uzeri .aspx sayfasi uzerinden Root’ta bulunan bir Folder’a kendi sistemimizden dosya aktaricaz. Direk isleme baslamak istiyorum. Olusturmus oldugumuz solution’a YuklenenKlasorler adli bir folder ve .aspx sayfasi ekliyoruz. Toolbox’tan FileUpload, ve button kontrollerini .aspx sayfamiza ekliyoruz. Button’un click eventine asagidaki kodlari yaziyoruz.
protected void Button1_Click(object sender, EventArgs e) { string DosyaUzantisi = FileUpload1.FileName. Substring(FileUpload1.FileName.LastIndexOf(".") + 1); if (DosyaUzantisi.ToLower() == "jpg" || DosyaUzantisi.ToLower() == "gif" || DosyaUzantisi.ToLower() == "xml") { FileUpload1.SaveAs(Server.MapPath("YuklenenDosyalar\\") + RastgeleKod + "." + DosyaUzantisi); } else { Label1.Text = "Hatali Dosya Secimi"; } }
Dosya uzantisini okumak icin. FileUpload.FileName.Substring(FileUpload.FileName.LastIndexOf(“.”) + 1) yani dosya adindaki son nokta karakterinden itibaren okuma islemi gerceklestirdik. IF blogu icerisinde kullanicinin aktarim yapabilecegi dosya turlerini belirtmis oluyoruz. Mesela yukaridaki ornegimizde kullanici sadece .jpg, .gif, ve .xml uzantili dosyalari, olusturmus oldugumuz YuklenenDosyalar isimli klasore aktarabilir. Bukadar basit.
4- Forms Authentication
Asp sadece IIS authentication metodlarını desteklerken asp.net daha geniş güvenlik sistemini destekliyor örneğin IIS/Windows doğrulama sistemlerinden Basic doğrulama, Digest doğrulama, Integrated Windows doğrulama, Form bazlı doğrulama ve Microsoft Passport doğrulama. asp.net içerisinde yeni olarak Windows kullanıcı doğrulama (windows authentication) sistemine ek olarak form bazlı kullanıcı doğrulama (forms-based user authentication) sistemi geliştirilmiştir. bu yeni sistemde çerez yönetimi (cookie management) ve otomatik olarak doğrulanmayan kullanıcıların başka bir web sayfasına gönderilmesi (automatic redirecting of unauthorized logins) gibi güzel özellikler eklenmiştir. İzlemek, Debug, ve Bellekleme Desteği (Tracing, debugging and caching support)asp sisteminde kodu izlemek ve BUG lari bulmak bir derttir. Fakat asp.net içerisinde bu sistem çok daha geliştirilmiş, adım adım debug olayı ve diğer trace ve debug metodlarini desteklemektedir. asp.net bunlara ek olarak mükemmel bellekleme (caching API) sağlamaktadır. Verileri bellekleme sistem output caching, data caching, dependent caching ve fragment caching metodlarını destekler.Alintidir.
Authentication Mode’umuzu belirlerken asp projemizde yer alan web.config dosyamizin icindeki configuration alanini sekildeki gibi duzenliyoruz.
<configuration><system.web>
<security>
<authentication mode="Forms">
</authentication>
</security>
</system.web>
</configuration>
Ve ayni sekilde web.config dosyamiz icerisinde kullanici bilgileride tanimlanabilir.
<configuration>
<system.web>
<authentication mode="Forms">
<forms name=".ASPXUSERDEMO" loginUrl="login.aspx"
protection="All" timeout="60">
<credentials passwordFormat="Clear" >
<user name="serkan" password="serkan"/>
<user name="kadir" password="kadir"/>
<user name="test" password="user"/>
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
<globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />
</system.web>
</configuration>
Gibi…Su an vaktim olmadigindan dolayi orneklerimizi 3. bolume sarkitiyorum.
ASP.Net Samples – Part I : Application Cache, and Cookies
Merhaba arkadaslar, bu makalemde sizlere ASP.NET icinde bulunan bir cok temel konudan bahsedecegim, ve bunlarla ilgili ornekler gostericem. Kisaca uzerinde duracagimiz konulari ve ornekleri listeleyecek olursak;
- Application Cache Sample
- Cookie Sample
- File Upload Sample
- Forms Authentication Sample
- Mail Send Sample
- Membership Sample
- Query String Sample
- Session State Sample
- Session LogIn Sample
- Trace Sample
- Web Part Sample
- ve Global.asax yapisi.
1- Application Cache Sample:
Girmis oldugunuz herhangi bir web sitesinde calisan applicationlarin, sizin localinizde calismasini saglayan yapi Cache yapisidir. Yani verilerin bellekte tutulmasidir. Buna ornek olarak; veritabanimizda bulunan bir tablodaki bilgileri alip .aspx sayfasinda bir gride basacagiz.
public DataTable GetCustomerData() { DataTable retVAL = new DataTable("Customers"); SqlDataAdapter SqlAdp = new SqlDataAdapter("SELECT * FROM Customers",
ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString); try { SqlAdp.Fill(retVAL); } catch (Exception ex) { retVAL = null; } finally { SqlAdp.SelectCommand.Connection.Dispose(); } return retVAL; }
Bu fonksiyonumuz, efsanevi DB olan Northwind’in
Customers tablosundan veri aliyor, ve bunu adi Customers olan bir DataTable icerisinde tutuyor. Peki gelelim bu yapiyi Cache kullanarak cagirmaya.
protected void Page_Load(object sender, EventArgs e) { if (Cache["CustomerData"] == null) { Cache.Add("CustomerData", GetCustomerData(), null, DateTime.Now.AddMinutes(3), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null); } GridView1.DataSource = Cache["CustomerData"]; GridView1.DataBind(); }
Ustte gormus oldugunuz Kod blogunda ise CustomerData isimli bir Cache olusturuyoruz, ve GetCustomerData() fonksiyonunu kullanarak, datayi Cache’e gomuyoruz. Cache’i silmek isterseniz kullanacaganiz kod adi uzerinde
Cache.Remove("CustomerData");
2- Cookie Sample
Cookies kelimesi aslinda hemen hemen her bilgisayar kullanicisinin anlamina ve islevine hakim oldugu bi kavramdir. Gunumuzde girdigimiz web sitelerinde, sitenin bizi tanimasi icin bazi bilgiler gireriz (e-mail, password, kullanici adi gibi). Bu islemi siteye her girisimizde tekrarlamamak adina, site Local diskinizde sizi taniyabilmek adina text dosyasi olusturur. Peki bu islem ne kadar guvenlidir diye soracak olursaniz, bana kalirsa cookie kullanmak pekte guvenli bi olay degildir. Girdiginiz sitelerde “Beni Hatirla” checkboxlari genelde cookie olusturma amaciyla kullanilir. Localinizde olusturulan bu text dosyalari bir komut dosyasi veya virus degildir, sadece size ozel bir tanimlamadir, ve tanimlamayi olusturan web sunucusu tarafindan okunabilir. Cookie ornegimize baslamadan once sekildeki gibi bir .aspx sayfasi olusturalim.
Button’umuzun Click eventinde su kodlari kullaniyoruz.
protected void Button1_Click(object sender, EventArgs e) { HttpCookie ck = new HttpCookie("SerkanCookie"); ck.Values.Add("Saat", DateTime.Now.ToLongTimeString()); ck.Values.Add("Deneme", TextBox1.Text); ck.Expires = DateTime.Now.AddDays(1); Response.Cookies.Add(ck); }
Bu islem ile, icerisinde textBox’imizi degerini barindiran bir Cookie yaratiyoruz, ve bu cookie icin bir expire suresi belirtiyoruz.
ck.Expires(DateTime.Now.AddDays(1)); komutu ile Cookie’mizin 1 gun sonra expire olacagi bilgisini belirtiyoruz.
Ve Form Load kisminda, su kodlari uyguluyoruz,
protected void Page_Load(object sender, EventArgs e) { if (Request.Cookies["SerkanCookie"] != null) { HttpCookie serkan = Request.Cookies["SerkanCookie"]; TextBox1.Text = serkan["Saat"] + " " + serkan["Deneme"]; } }
Boylece Form’u tekrar Run ettigimiz zaman, sistem kayitli olan Cookie dosyasini bulmaya calisip icindeki bilgileri textBox’a yazar.
2. makalemde File Upload ve Forms Authantication konularina deginecegim.












