Debug işlemleri yaparken sıklıkla karşılşatığımızın durumların başında nesnemiz başka bir nesneyi içeriyorsa bu nesneyi ancak hiyeraşik bir biçimde inceleme şansına sahip oluyoruz. Aşağıdaki resimde daha net birşekilde ne demek istediğim belli oluyor.

Görüldüğü gibi Report nesnemiz içerde List<int> türünden Results özelliğine (property) sahip. Bu özelliğin hangi değerlerini tuttuğunu görmek için + ile detayına inip bakmamız gerekiyor. Bu özellik baska bir nesneyi temsil ediyor, ve o nesne de içerisinde iç içe (nested ) başka değerleri tutuyor olabilir. Bu durumda + lar ile detaylara inip boğulabilirsiniz ;-) Ama çoğumuz bu iç içe nesnelerin aslında sadece işimize yarayacak kısmını debug işlemi sırasında görmek isteyebilir, hatta bu kısımları özelleştirerek istediğimiz gibi bir görüntü sağlayabiliriz. Aşağıdaki resim ile bir önceki resimi kıyaslayarak debug işlemi sırasındaki görüntüleri karşılaştırabilirsiniz.

Bu görüntünün sağlabilmesi için yapmamız gereken Report nesnemizin debug işlemi sırasında görünmesini isteyeceğimiz şekilde bir proxy class'ını hazırlamak.

[DebuggerTypeProxy(typeof(ReportDebuggerProxy))]
    public class Report
    {
        private DateTime _date;
        public DateTime ReportDate
        {
            get { return _date; }
            set { _date = value; }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private List<int> _results = new List<int>();
        public List<int> Results
        {
            get { return _results; }
            set { _results = value; }
        }

        private int _dummy;
        public int Dummy
        {
            get { return _dummy; }
            set { _dummy = value; }
        }

    }

Report nesnemize DebuggerTypeProxy attribute'nün uygulandığı dikkatinizi çekmiştir. Bu atrribute sayesinde Report nesensi debug işlemi sırasında sanki Report türünden bir nesne değil de ReportDebuggerProxy nesnesinin bir görüntüsüymüş gibi karşımıza çıkacaktır. Şimdi proxy görevini görecek sınıfımızı yazalım.

public class ReportDebuggerProxy
    {
        Report _report;
        public ReportDebuggerProxy(Report report)
        {
            _report = report;
        }

        public string ReportDate
        {
            get { return _report.ReportDate.ToLongDateString();}
        }
        public string Name
        {
            get { return "Raport Name : " + _report.Name; }
        }

        public string Results
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                foreach (int result in _report.Results)
                {
                    sb.Append("(");
                    sb.Append(result.ToString());
                    sb.Append(") ");
                }
                return sb.ToString();
            }
        }
    }

Görüldüğü gibi debug sırasında görmek istediğimiz özellikleri belirtiyoruz. Proxy sınıfında dikkat ederseniz Report sınıfındaki Dummy özelliğine yer verilmemiş ve diğer özellikler ise görülmek istendiği şekilde özelleştirilmiş.

 


 
Categories: .NET | C# | Inceleme

İçerğin yoğun olduğu aspx sayfalarda scroll ile sayfanın aşağılarına inip bir post işlemi gerçekleştirdiğinizde postback işleminden sonra kendinizi sayfanın başında bulacaksınız. Oysaki ben tekrar post işleminin yapıldığı yere sayfayının pozisyonunu ayarlamasını isterim. O zaman yapılacak şey Page direktifine gidip MaintainScrollPositionOnPostback özelliğini (attribute) eklemektir.

<%@ Page Language="C#" AutoEventWireup="true" MaintainScrollPositionOnPostback="true" CodeFile="..." Inherits="..." %>

Windows uygulamarında Enter'a bastığımızda (AcceptButton) nerde olursak olalım belirli bir butona tıklanmış gibi işlem yapabiliyoruz. Peki ASP.NET'te bunu sağlarız. Yapacağımız form tagına gidip DefaultButton özelliğini eklemek olacaktır.

<form id="form1" defaultbutton="Button1" runat="server">

Bazen de sayfa yüklendiğinde sayfadaki belirli bir kontrolün aktif olmasını isteyebiliriz. Örneğin bir login sayfasını düşünelim. Sayfa yüklendiğinde imlecimizin kullanıcı adı girişi yapılacak textbox'un içinde olmasını isteriz. Ya da sayfa yüklendiğinde belirli bir butonun seçili olamasını sağlamak isteyebiliriz. Bu durumda form tagına gidip defaultfocus propertisini eklemek olacaktır.

<form id="form1" defaultfocus="TextBox1" defaultbutton="Button1" runat="server">


 
Categories: Asp.net

September 20, 2007
@ 11:12 PM

Küçük bir ayrıntı olmasına karşın kullanışlı bir özellik. Aşağıdaki kodu test ederken label'lara tıkladığınızda aralarındaki farkı anlayacaksınız. (AssociatedControlId özelliği verilmiş label'a tıkladığınızda textbox kontrolü focus'lanacaktır)

<asp:Label id="label" AssociatedControlId="textbox" Text="Ad" runat="server" /><asp:TextBox id="textbox" runat="server" /><br />

<asp:Label id="label1" Text="Soyad" runat="server" /><asp:TextBox id="textbox1" runat="server" />

Render işleminde sonra çıkan sonuç ise şöyle :

<label for="textbox" id="label">Ad</label>
<input name="textbox" type="text" id="textbox" /><br />
<span id="label1">Soyad</span>
<input name="textbox1" type="text" id="textbox1" />


 
Categories: Asp.net | Code

September 11, 2007
@ 01:10 AM

Tools->Options dan çıkan pencerede Environment->Start Up'ı şeçiyoruz,bu kısımdaki At startup seçeneklerinden show empty environment i seçerek açılışta VS.NET 2005'i yavaşlatan Start Up Page'i kaldırabiliyoruz.

Diğer tercihimiz de açılışta karşımıza çıkan splash screen'i kaldırmak. Bunun için de VS.NET 2005 için masa üstünüzde bir kısayol oluşturun.Sağ tıklayıp properties dediğimizde açılan pencereden Shortcut Tab'ını seçip, Target kısmındaki bölüme /nosplash parametresini ekleyerek biraz olsun VS.NET 2005'in açılışını hızlandırabiliriz.


 
Categories: .NET | Inceleme

September 3, 2007
@ 10:06 PM
Ctrl+F ile VS.NET 2005'de gelişmiş şekilde arama işlemleri yapabiliyoruz. Bir başka arama şekli de şöyle (Incremental Search demiş MS)

Ctrl + I tuş kombinasyonunu uyguluyoruz açık bir kod penceresinde. Ikon değiştikten sonra (dürbün ve aşağı ok şeklinde bir ikon beriliyor) sonra aramak istediğimiz kelimeyi yazıyoruz. O ana kadar yazdığımız kelime ile eşleşen bir kelime bulunduğunda şeçili hale getiriliyor.( Firefox kullananlar için yabancı gelmeyecektir bu arama şekli ;) ) Tekrar Ctrl + I ya bastığımızda bir sonraki eşleşen bulunur. ESC ile aramdan çıkılır, Ctrl + Shift + I ile de bir önceki bulunana gidilir.




Ha unutmadan editörde belirli bir alanı seçmek istiyorsanız da Alt tuşuna basarak seçim işlemini gerçekleştirin.



 
Categories: .NET | Inceleme

September 2, 2007
@ 11:10 PM

GAC (Global Assembly Cache) tüm uygulamaların ortak kullandığı (shared assembly) assembly'lerin tutulduğu özel bir dizindir. Genellikle C:\windows\assembly dizinidir (%windir%\assembly). Bu dizine girip baktığımızda alışık olmadığımız bir yapı ile karşılaşacağız. E özel dedik ya ;)

E peki bu dizini normal dizin gibi görme şansımız yok mu? Var! şöyle ki;

1- Başlat -> Çalıştır -> regedit -> Enter
2- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion bölümüne geliyoruz.
3- Bu kısma "Binary Value" ekleyip ismini DisableCacheViewer verip, değerini de 1 olarak ayarlıyoruz.

İşlem bitti, artık ilgili dizine gidip baktığınızda bildik bir dizin ile karşılacaksınız.Ha bu işlemi neden mi yaptık? Belki bir dll çok hoşumuza gitti, decompile edip inceleyeceğiz, olmadı alıp bunu direk projeme eklicem (xcopy)...Olamaz mı ?


 
Categories: .NET

September 2, 2007
@ 10:52 PM

Çok uzatmadan konuya direk gireyim. Kendi nesnemize ait bir dizimizi debug yaparken aşağıdaki gibi görürüz.

Yine Namespace.NesneIsmi yapısı karşımızda.Hmm diyor nesnemize ait class bildiriminde ToString metodunu override ediyoruz.

public override string ToString()
{
   return Name;
}

Bundan sonra yeniden duruma baktığımızda aşağıdaki gibi daha anlaşılır bir görüntü ile karşılaşıyoruz.


 
Categories: .NET

September 2, 2007
@ 09:38 PM

ASP.NET uygulamarınızda kullanıcılardan dosya transferi yapmak istediğimizde FileUpload Asp.net sunucu kontrolü ile basit bir şekilde bu işlemi hallederiz.Basit bir örnek ile

if (FileUpload1.HasFile)
{
   try
   {
      FileUpload1.SaveAs(Server.MapPath(".") + "/uploads/" + FileUpload1.FileName);
   }
   catch (Exception exp)
   {
      //hede höde
   }
}

Tabi dosyaları saklayacağınız dizine yazma hakkı (ASP.NET kullanıcısına) vermeliyiz. Buraya kadar herşey doğal gibi görünse de unuttuğumuz küçük! bir ayrıntı var ki o da dosya boyutu ve dosya tipi. Öncelikle istemediğimiz dosya tiplerinin sunucumuza upload edilmesini önlemeliyiz. Kullanıcıdan sunucuya gönderilen dosya tipini

Response.Write(FileUpload1.PostedFile.ContentType);
//bir txt dosyasını gönderdiğinizde tarayıcımızda "text/plain",bir mp3 dosyası göndediğimizde ise "audio/mpeg" yazdıgını göreceğiz.

kod satırı ile öğrenebilir ve istemediğimiz tipdeki dosyaların sunucuya gönderilmesini engelleyebiriz.Peki gelelim dosya büyüklüğüne. Bu basit hali ile uygulamamızı kullanıcılara açtığımızda beklenmedik bir durum ile karşılaşma ihtimalimiz çok yüksek. Örneğin iş başvurusu yapılacak ve kullanıcılardan CV lerini word dökümanı olarak istemekteyiz. ContentType ile dosya tipini belirleyerek başka formatlardaki dosyaları sunucumuza gönderilmesini engelledik. E güzel!. Dosya boyu 5 mb olan bir kullanıcı CV sini göndermeye çalıştığında ne olur ? Görünürde "ne olabilir ki?" dediğimizde aslında sunucumuz - iis - bu işlemi iptal edecek ve hatta yukardaki kod örneğinde catch bloğumuz işe yaramayacaktır. Olan olmuştur. Sunucu bir request'deki varsayılan büyüklük olan 4MB  sınırının aşıldığını tespit edecek ve bir hata oluşturacaktır (HttpUnhandledException). Peki Global.asax da biz bu hatayı yaklayıp inceleyelim.

Görüldüğü gibi yakalanan hatamızın InnerException nesnesine baktığımızda oluşturulan isteğin sınırı aştığını görebiliriz. Bu bizim için aslında dezavantajdan ziyada avantajdır.Çok büyük dosyalar yükleyerek sistemimizin yavaş çalışmasına neden olacak kötü niyetli arkaşlarımızı! birazcık üzecektir.  Çözüm ise sunucumuzun gelen isteklerin boyutunun 4MB den büyük olmasına izin vermesi. Bunu da web.config doyasını aşağıdaki gibi düzenleyerek sağlayabiliriz.

<httpRuntime maxRequestLength="16384"/>

Artık sunucumuz bu ayar ile maksimum istek boyutunu yaklaşık 16MB olarak kabul edecektir. Tabi burda dikkat etmemiz gereken en önemli nokta ise sunucumuzun bu uzun işlemler sırasında -16MB lik bir dosya kullanıcının bağlantısı yavaş olduğunu göz önüne alındığında yüklenmesi uzun bir işlem olacaktır - Normalde 90 sn boyunca gelen isteğe cevap veremezse IIS, isteği sonlandıracak ve timeout hatası gönderecektir. Bunu da engellemek için web.config dosyamızda aşağıdaki düzenlemeyi yaparız.

<httpRuntime maxRequestLength="20000" executionTimeout="360"/>

artık sunucumuz 90 sn değil 360 sn boyunca gelen isteği cevaplamak için "var gücü ile :) " çaba sarfedecektir ;) Tabi bu süreyi iyi analiz etmeli performans sorunları yaşamamak için bu sürenin uygulamanız çerçevesinde ne kadar süre olarak belirlenmesini iyi analiz etmek gerekir.


 
Categories: Asp.net