Archive for the ‘ASP.NET’ Category
ASP.NET 4.0 – URL Routing
Web uygulamarında kullanıcıların yapmış olduğu işlemlerde parametre aktarımı bazı durumlarda QueryString ile (URL’den) yapılmaktadır. Bu durumda adres çubuğunda oluşan link çok uzun ve okunamaz hale geliyor. Bu kullanıcı açısından görüntü kirliliği yaratıyor, arama motorları tarafından indexlenme ihtimalini azaltıyor ve geliştirici açısından parametrelerin okunması ve takip edilmesi zorlaştırıyor. Örneğin;
<I>http://semgoksu.com/search.aspx?Kategori=ASP.NET&Tarih=15122009&Baslik=URLRouting</I>
ASP.NET 4.0 ile birlikte URL Routing’i kullanarak bu sorunu ortadan kaldırabiliyoruz. Bu sayede hem oluşan link daha kısa ve anlamlı oluyor, hemde URL içerisindeki klasör yapısına sayfa ile ilgili keywordleri koyarak arama motorlarının daha kolay indexlemesini ve bu sayede sayfalarımızın daha üst sıralarda çıkması sağlayarak büyük bir avantaj sağlamış oluyoruz. Yukarıda vermiş örneği ASP.NET 4.0 URL Routing’i kullanarak aşağıdaki gibi yapabiliriz.
<I>http://semgoksu.com/Arama/ASP.NET/15122009/URLRouting</I>
URL Routing ilk olarak MVC ile birlikte geldi ve artık ASP.NET 4.0 ile birlikte URL Yönlendirme işlemi yapabilmemiz için her şey hazır durumda. Visual Studio 2010’u kullanarak yeni bir ASP.NET uygulaması oluşturalım ve konuyu örneklendirelim. Uygulamayı oluşturduktan sonra web uygulamamıza yeni bir Global.asax dosyası ekleyelim.
Globax.asax dosyası içerisinde bulunan <I>Application_Start</I> methodu içerisinde URL yönlendirme işlemini yapacağız. Bunun için ihtiyacımız olan ilk şey <I>RouteTable</I>. Bu sınıf farklı formatlardaki url yönlendirmelerini(Route’ları) saklayacak olan Route koleksiyonudur. İki parametre alır; Route’un adı ve Route nesnesi. <I>Route</I> nesnesi de URL’in gösterileceği formatı belirtmek için kullanılır. Uygulamaya gelen istekler Route’un formatına uygunsa PageRouteHandler’ın belirttiği path’e yönlenir. <I>PageRouteHandler</I> sınıfı yönlendirilecek olan fiziksel dosyayı Constructor’da(Yapıcı metot) parametre olarak alır.
Sonuç olarak sayfaya yapılan request’lar RouteTable’daki Route’lardan birine uygun formattaysa PageRouteHandler’in işaret ettiği sayfaya yönlenir. URL bizim belirttiğimiz formatta görüntülenirken arka tarafta ilgili fiziksel dosya üzerinde işlem yapılır.
İlk olarak ana sayfamızdan(Default.aspx) detay sayfaya (detay.aspx) sayfasına bir yönlendirme işlemi yapalım. Detay sayfasına bir de parametre gönderelim ve bu parametreyi detay sayfada yakalayarak ekran da görüntüleyelim.
[Global.asax]
<%@ Application Language="C#" %>
<%@ Import Namespace="System.Web.Routing" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add("Detay", new Route("Detay/{Parametre}", new PageRouteHandler("~/Detay.aspx")));
}
</script>
</DIV>
Appplication_Start metodu içerisinde sayfamıza gelecek olan url formatını <I>Klasor/{Parametre}</I> şeklinde belirttik. ({Parametre} yerine istediğimiz bir değeri gönderebileceğiz) Bu formatta gelen bütün istekler detay.aspx sayfasını gösterecek.
[Default.aspx]
<asp:HyperLink ID="link" runat="server" NavigateUrl=’<%$ RouteUrl:RouteName=Detay, Parametre=Sayfa1 %>’>Detaya Git</asp:HyperLink>
</DIV>
Ana sayfaya bir HyperLink nesnesi ekledik. HyperLink içerisinde ilk olarak sayfamızın gideceği Route’u ve o Route’a göndereceğimiz Parametreyi bildirdik. Oluşacak olan format şu şekilde olacak. NavigatetUrl içerisinde kullanılan RouteUrl’i kod tarafında kullanamıyoruz.
<I>http://localhost:50751/Detay/Sayfa1</I>
Şimdi Detay.aspx sayfaya gidelim ve gönderdiğimiz parametreyi yakalayalım. Route içerisinde gönderdiğimiz bütün parametreler RouteDataiçerisinde yer alır. Göndermiş olduğumuz parametreye erişmek için RouteData.Values[“Parametre”] yada RouteData:Name şeklinde kullanırız.
[Detay.aspx.cs]
protected void Page_Load(object sender, EventArgs e)
{
if (RouteData.Values["Parametre"]!=null)
{
Response.Write(RouteData.Values["Parametre"].ToString());
}
}
</DIV>
Sayfayı çalıştırdığımız da URL istediğimiz şekilde gitmiş ve Detay.aspx sayfasına göndermiş olduğumuz parametreyi’de ekranda görüntüledik.
Şimdi farklı bir örnek yapalım ve birden fazla parametreyi nasıl göndeririz ona bakalım. Bu örnekte SQL Server 2005’te yer alan örnek veritabanlarından AdventureWorks’u kullanarak Kategorileri ilk ekran da listeyelim. Kullanıcı ilgili kategoriye tıkladığında farklı bir sayfa da ilgili ürünler listelensin. Sayfaya göndereceğimiz URL formatını da istediğimiz gibi değiştirelim. Bunun için global.asax dosyamızı düzenleyelim. Route içerisinde format istediğimiz gibi düzenleyebiliriz. KategoriID ve KategoriAdi parametrelerini istediğimiz değerleri verebileceğiz.
[Global.asax]
<%@Application Language="C#" %>
<%@ Import Namespace="System.Web.Routing" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add("Kategoriler", new Route("Katgoriler/{KategoriAdi}/{KategoriID}", new PageRouteHandler("~/Detay.aspx")));
}
</script>
</DIV>
Sayfamıza bir Repeater ekleyelim. Burada Kategorileri listeleyeceğiz. Veritabanındaki verilere erişmek için projemize bir adet <I>LINQ to SQL Classes</I> Dosyası ekleyelim. İsim olarak AdventureWorks diyelim.
Kullanacağımız ProductSubCategory ve Product tablolarını’da dosyamıza alalım. Şimdi kategorilerimizi listeleyek olan HTML kodunu yazalım. Sayfaya Repeater, içerisinede bir HyperLink ekliyoruz.
[Default.aspx]
<asp:Repeater ID="rptKategoriler" runat="server" OnItemDataBound="rptKategoriler_ItemDataBound">
<ItemTemplate>
<asp:HyperLink ID="hlKategori" runat="server">
</asp:HyperLink><br />
</ItemTemplate>
</asp:Repeater>
</DIV>
Şimdide veritabanından verileri LINQ to SQL ile çekelim ve Repeater’a bağlayalım. ItemDataBound eventin’de HyperLink nesnesini yakalayıp kontrolün Text ve NavigateUrl özelliğini datadan gelen değer ile dolduracağız.
[Default.aspx.cs]
AdventureWorksDataContext db = new AdventureWorksDataContext();
protected void Page_Load(object sender, EventArgs e)
{
rptKategoriler.DataSource = (from k in db.ProductSubcategories select k).Take(10); // 10 kayıt alalım
rptKategoriler.DataBind();
}
protected void rptKategoriler_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item|| e.Item.ItemType == ListItemType.AlternatingItem )
{
HyperLink hl = e.Item.FindControl("hlKategori") as HyperLink;
hl.Text = DataBinder.Eval(e.Item.DataItem, "Name").ToString();
RouteValueDictionary parameters = new RouteValueDictionary()
{
{ "KategoriID", DataBinder.Eval(e.Item.DataItem, "ProductSubCategoryID").ToString() },
{ "KategoriAdi",DataBinder.Eval(e.Item.DataItem, "Name").ToString() }
}; // Route’un alacağı parametreler’i dinamik olarak dolduruyoruz
VirtualPathData path = RouteTable.Routes.GetVirtualPath(null,"Kategoriler", parameters);
hl.NavigateUrl = path.VirtualPath; // Oluşan Route’un pathini hyperlinke atadık.
}
}
</DIV>
Kategorilerin listeleneceği sayfayı hazırladık. Şimdi de gidip detay sayfada görüntülenecek olan ürünler için gerekli sayfayı hazırlayalım. İlk olarak HTML’e bir Repeater ekleyelim ve içine bir label atalım. Text özelliğinde de ürün’ün adını görüntüleyelim.
[Detay.aspx]
<asp:Repeater ID="rptUrunler" runat="server">
<ItemTemplate>
<asp:Label ID="lblUrunAdi" runat="server" Text=<%# Eval("Name") %>>
</asp:Label><br />
</ItemTemplate>
</asp:Repeater>
</DIV>
Veriyi LINQ to SQL ile çekerek Repeater’a bağlayalım. Diğer sayfadan gelen KategoriID parametresinide almayı unutmuyoruz. Ürünler gelen KategoriID parametresine göre listelenecek.
[Detay.aspx.cs]
AdventureWorksDataContext db = new AdventureWorksDataContext();
protected void Page_Load(object sender, EventArgs e)
{
if (RouteData.Values["KategoriID"]!=null)
{
int UrunID = Convert.ToInt32(RouteData.Values["KategoriID"]);
UrunleriGetir(UrunID);
}
}
private void UrunleriGetir(int KategoriID)
{
rptUrunler.DataSource = from u in db.Products
where u.ProductSubcategoryID == KategoriID
select u;
rptUrunler.DataBind();
}
</DIV>
Şimdi sayfayı çalıştıralım ve sonuca bakalım,
Kategorilerden birine tıklayalım.
İşte bu kadar J
Bu makalenin de sonuna geldik başka bir makale de 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 – Page.Description ve Page.Keyword Özellikleri
ASP.NET 4.0 ile birlikte Page sınıfına Description ve Keyword isimli iki yeni özellik eklendi. Bu özellikleri kullanarak web uygulamalarına keywords ve desctiption meta etiketlerini ekleyebiliyoruz.
ASP.NET 4.0 Öncesi
ASP.NET 4.0 öncesinde keywords ve description meta etiketlerini <head> etiketi arasına yazabiliyorduk.
<headrunat="server">
<title>Page Description ve Page Keyword Özelliği</title>
<meta name="keywords" content="Buraya sayfa ile ilgili anahtar kelimeler gelecek..’ />
<meta name="description" content="Buraya sayfanın açıklaması gelecek…" />
</head></DIV>
ASP.NET 4.0 Yaklaşımı
ASP.NET 4.0 ile birlikte sayfa direktiflerinden Keywords ve Description özelliğini kullanarak meta etiketini belirleyebiliyoruz.
[HTML]
<%@
Page Language="C#"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
Keywords="Anahtar kelimeler…"
Description="Sayfa ile ilgili açıklama…"
%></DIV>
Bu bilgilerin veritabanından geleceğini de düşünürsek bu işlemi dinamik olarak da yapabiliriz.
[C#] protected void Page_Load(object sender, EventArgs e)
{
this.Keywords = "Anahtar kelimeler…";
this.Description = "Sayfa ile açıklama…";
}</DIV>
Eğer sayfada head etiketi arasında tanımlı keywords yada description meta etiketi varsa bizim belirlediğimiz bilgiler üzerine yazılacaktır.
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.
Microsoft .Net Framework 4.0 – Chart Technology (PART II)
Bir onceki yazimda, chart hakkinda ufak bir bilgi verip, source kodlari ile yapilisi hakkinda bir ornek yapmistim. Bu makalede, olayi biraz daha ust bir boyuta tasiyip, kullanacagimiz chart’a DataBind yapip, kod tarafinda dinamik bir chart olusturacagiz. Senaryo olarak, bir ogrencinin quizlerinden, midtermlerinden, ve finalinden almis oldugu notlari bir chart kullanarak raporlayacagim.
SQL – Serverda kullanacagim veriler icin altyapiyi olusturalim. Ogrenci tablosu icinde ogrencinin Adi-Soyadi, Quiz1, Quiz2, Quiz3, Quiz4, Quiz5, Midterm1, Midterm2, ve Final isimli fieldlarim olsun.
Sekilde gordugunuz gibi iki ogrenci icin Quiz,Midterm, ve Final notlarini DB’de tutuyorum.
Algoritmamiza gore oncelikle, datanin tutulacagi bir DataTable olusturuyoruz, ardindan data’yi cekip olusturdugumuz DataTable’a Bind ediyoruz, ve Fieldlardaki degerleri Chartimizda olmasi gereken yerlere set ediyoruz. Asagidaki kod blogunu uygulayarak.
Oncelikle .aspx sayfamiza bir tane Chart surukleyip birakiyoruz, ve gereken degerleri set ediyoruz:
1: <asp:Chart ID="studentGradesChart" runat="server">
2: <Series>
3: <asp:Series Name="Student" ChartType="Line" YValuesPerPoint="2">
4: </asp:Series>
5: <asp:Series Name="Student2" ChartType="Line" YValuesPerPoint="2">
6: </asp:Series>
7: </Series>
8: <ChartAreas>
9: <asp:ChartArea Name="ChartArea1">
10: </asp:ChartArea>
11: </ChartAreas>
12: </asp:Chart>
Ve sayfamizin Page_Load kismini bu kodlari koyuyoruz.
1: if (!Page.IsPostBack)
2: {
3: // DataTable olusturma
4: DataTable dt = new DataTable();
5: dt.Columns.Add("Isim", typeof(string));
6: dt.Columns.Add("Soyisim", typeof(string));
7: dt.Columns.Add("Quiz1", typeof(int));
8: dt.Columns.Add("Quiz2", typeof(int));
9: dt.Columns.Add("Quiz3", typeof(int));
10: dt.Columns.Add("Quiz4", typeof(int));
11: dt.Columns.Add("Quiz5", typeof(int));
12: dt.Columns.Add("Midterm1", typeof(int));
13: dt.Columns.Add("Midterm2", typeof(int));
14: dt.Columns.Add("Final", typeof(int));
15: dt.AcceptChanges();
16:
17: // istenilen datayi cekiyoruz
18: StudentObjectModelDataContext dc = new StudentObjectModelDataContext();
19:
20: List<Student> secilenOgrenciler = (from s in dc.Students select s).ToList();
21:
22: foreach (Student ss in secilenOgrenciler)
23: {
24: // Datayi, satirlara yerlestiriyoruz.
25: object[] row = new object[]
26: {
27: ss.StudentName,
28: ss.StudentLastName,
29: ss.Quiz1,
30: ss.Quiz2,
31: ss.Quiz3,
32: ss.Quiz4,
33: ss.Quiz5,
34: ss.Midterm1,
35: ss.Midterm2,
36: ss.Final
37: };
38: dt.Rows.Add(row);
39: }
40:
41: // Gelen Datayi, DataTable'a bagliyoruz
42: studentGradesChart.DataSource = dt;
43:
44: // Chart tipi secimi. Bu asamada bircok cesitten istediginizi secebiliyorsunuz.
45: studentGradesChart.Series["Student"].ChartType = SeriesChartType.Line;
46: studentGradesChart.Series["Student2"].ChartType = SeriesChartType.Line;
47:
48: int seriesIndex = 0;
49: foreach (DataRow dr in dt.Rows)
50: {
51: // Bu sekmede chart ozelliklerini customise ediyoruz.
52: // Kullanisli olan bircok property mevcut
53: studentGradesChart.Series[seriesIndex].MarkerStyle = MarkerStyle.Cross;
54: studentGradesChart.Series[seriesIndex].MarkerSize = 8;
55: studentGradesChart.Series[seriesIndex].MarkerBorderWidth = 7;
56: studentGradesChart.Series[seriesIndex].ToolTip = String.Format("Student Number : {0}", seriesIndex + 1);
57:
58: // Degerleri Chart'a set ediyoruz.
59: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 1", dr["Quiz1"]);
60: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 2", dr["Quiz2"]);
61: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 3", dr["Quiz3"]);
62: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 4", dr["Quiz4"]);
63: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 5", dr["Quiz5"]);
64: studentGradesChart.Series[seriesIndex].Points.AddXY("Midterm 1", dr["Midterm1"]);
65: studentGradesChart.Series[seriesIndex].Points.AddXY("Midterm 2", dr["Midterm2"]);
66: studentGradesChart.Series[seriesIndex].Points.AddXY("Final", dr["Final"]);
67:
68: seriesIndex++;
69: }
70: }
Kod’u Run ettigimizde sekildeki gibi bir goruntu elde ediyoruz:
Elimden geldigince fikir edinmek adina, bir ornek yaptim. Tabii ki Chart konusu son derece derin bir konu. Bu konu ilgili bilgi edindikce bunlar ile ilgili ornekler yapmaya devam edecegim. Islerimin yogunlugundan firsat bulursam, bir sonraki asamada bir sirkete bagli olan alt kurumlarin ay bazinda yapmis oldugu cirolari gosteren bir chart yapmayi planliyorum.
Serkan Hekimoglu.
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.
Microsoft .Net Framework 4.0 – Chart Technology
Merhaba, bu makalemde sizin icin .Net Framework 4.0 ile gelen Chart teknolojisi uzerinde inceleme ve ornek yapacagim.
Chart nedir? Chart gundelik hayatta bile her yerde gorebilecegimiz grafikler ile gosterilen istatistiklerdir. Kullananlar bilirler ki .Net 3.5 doneminde chart kullanmak icin component indirirdik, fakat artik VS2010 ile bu component default olarak geliyor, ve ASP.NET projelerimizde Add-On kullanmadan Charting teknolojisini kullanabiliyoruz. Microsoft’a bu guzelliginden dolayi tesekkur ederiz
Hemen ufak bir ornek ile Chart teknolojisi kullanimi hakkinda ufak bir bilgi edinelim, ve VS2010’umuzu acip bir ASP.NET projesi olusturalim.
Gordugunuz uzere Toolbox > Data sekmesinde Chart Componenti default olarak gorunmektedir. Ustelik kullanimi da oldukca basittir. Bu yapiyi kullanmak icin Configuration File’a herhangi bir registration yapmaya gerek yoktur.
Olusturmus oldugumuz bir .aspx sayfasina Chart componentini surukleyip birakalim.
Eklemis oldugunuz Chart componentinin goruntusunude sekildeki gibi degistirebilirsiniz:
Source kismina gecerek Hard Coded olarak cok kucuk bir ornek yapmak istiyorum. Istanbul icin tahmini 5 gunluk hava durumu gosteren bir chart hazirlayip, gun gun hava sicakligini belirtelim.
Bir Charta default olarak value set etmek icinde sekilde gormus oldugunuz gibi Hard Coded olarak DataPointlerin, AxisLabel ve koordinat sistemindende bileceginiz uzere YValuelarinin degerlerini set edip, refresh ettigimizde sekilde ki goruntuyu elde ediyoruz:
Ilk kismi burada bitiriyorum. Ikinci kisimda daha detayli bir sekilde Chartlara DB’den databind edip dynamic olarak islemler yaptirmaya yonelik ornek yapacagim.












