Postback işleminde Asp.Net kontrolünü disable etmek

C#, VB.NET, ASP.NET Add comments

Özellikle yeni bir kaydın yapılacağı sayfalarda KAYDET butonuna birden fazla tıklandığı zaman veritabanında mükerrer kayıt oluşmaktadır. Bunu engellemek için ASP.NET öncesi teknolojilerde submit butonu gibi formu submit eden kontrolü JavaScript yardımıyla önce disable edip ardından formu submit ediyorduk.

Aynı mantığı ASP.NET server kontrolleri için de uyguladığımızda kontrolün disable olduğunu ancak postback işlemini gerçekleştirmediğine şahit oluruz. Event metodu verilmiş bir buttonu aşağıdaki gibi kodlayalım;

Merhaba

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Page_Load çalıştı.");
}

protected void Button1_Click(object sender, EventArgs e)
{
    Response.Write("Button1_Click çalıştı.");
}

Buttona tıklandığı zaman button disable olur ancak form submit edilmez. Formu submit etmesini de söyleyelim.

Bu durumda, button, disable olur ancak yine postback işlemi gerçekleşmez sadece formu submit edilmiş olur. Dolayısıyla sadece Page_Load metodu çalışmış olur.

Bu sorunu birkaç şekilde aşabiliriz, öncelikle klasik bir yöntemle bunu aşalım. Buradaki sıkıntımız, formu submit ettikten sonra sunucu tarafına submit button bilgisinin geçmemesidir. Sunucu tarafında sunucuya gelmiş requestleri okuyalım;

protected void Page_Load(object sender, EventArgs e)
{
    foreach (string Key in Request.Form)
    {
        Response.Write(Key + " : " + Request[Key] );
    }
}

Sayfayı bu haliyle submit ettiğimizde sadece TextBox1 nesnesinin geldiğini Button1 ile ilgili bir içeriğin gelmediğini görürüz.
__VIEWSTATE : ********
TextBox1 : Merhaba
__EVENTVALIDATION : ********

Demek ki eğer submit işlemiyle birlikte button bilgisini de yollarsak sorunu aşmış oluruz. Bunun için sayfamıza bir tane hidden input tanımlayıp form submit edildiği zaman bu input kontrolünü adı bizim submit buttonın adı olarak set edeceğiz. Dolayısıyla sanki submit buttonu tıklanmış gibi olacak. Hidden kontrolünün adı, __WhichSubmitButton olsun. Bu işlemi gerçekleştirecek javascript fonksiyonu da SubmitForm olarak isimlendirelim.

Merhaba

Şimdi, formu submit edelim.
Page_Load çalıştı.
__VIEWSTATE : **
Button1 :
TextBox1 : Merhaba
__EVENTVALIDATION : **
Button1_Click çalıştı.
Buradaki sıkıntımız da şudur; eğer sayfada ASP.NET validator kontrollerden biri varsa validation işlemi gerçekleşmeden form submit edilir. Bunun için ASP.NET’in sunduğu __doPostBack client tabanlı fonksiyon kullanılır. Bu metod, sayfada validator kontroller bulunduğu zaman otomatik olarak HTML içeriğe eklenir. Postback işlemi gerçekleşeceği zaman öncelikle sayfanın validation işlemleri yapılır(ValidatorOnSubmit metodu) daha sonra __doPostBack metodu çağrılır. Bu metod, __EVENTTARGET isimli değişkeni set eder. Sunucu da kendisine submit edilen bu değişkenin değerine bakarak ilgili kontrolün eventini tetikler.
Sayfadaki doğrulama işlemlerinin yapılıp yapılmadığı Page_ClientValidate() fonksiyonuyla öğrenilir. ASP.NET’in __doPostBack metodunu aktifleştirmek için Page sınıfının GetPostBackEventReference metodu kullanılır. Bu metodu, Page_Load aşamasında çağırmamız yeterli olacaktır. Sunucu tarafındaki Page_Load ve istemci tarafındaki SubmitForm metodlarını aşağıdaki gibi düzenleyelim.

protected void Page_Load(object sender, EventArgs e)
{
this.Page.GetPostBackEventReference(this.Button1);
}

Buradaki javascript kodu da Page_Load metodunda yazdırılabilirdi. Artık bu şekilde mükerrer tıklamayı engellemiş olduk. Eğer her sayfanın Page_Load’inda bunu yazmak istemiyorsanız klasik yöntemimizle ASP.NET yöntemini birleştirerek bütün sayfalar için ortak bir javascript fonksiyonu oluşturulabilir. .js dosyasında aşağıdaki fonksiyonu tanımlayalım. Daha sonra kullanılacak sayfalara import edip hangi submit buttonunda kullanmak istersek o button için OnClientClick=”SubmitForm(this)” çağrısını ekleyeceğiz.

function SubmitForm(Obj){
    if (typeof(Page_ClientValidate) == 'function') {
        if(Page_ClientValidate()){
            Obj.disabled=true;
            __doPostBack(Obj.id,'');
        }
    }else{
        var hdnKontrol=document.getElementsByName('__WhichSubmitButton');
        hdnKontrol.item(0).setAttribute('name',Obj.getAttribute('name'));
        Obj.disabled=true;
        Obj.form.submit();
    }
}

Bu yöntemde validatorlerin olmadığı sayfalara __WhichSubmitButton isimli hidden kontrolünü eklemeyi unutmamalıyız.

18 Responses to “Postback işleminde Asp.Net kontrolünü disable etmek”

  1. Cenk ŞAHİN Says:

    Hocam masterpage içeren formlarda bu scriptiniz maalesef çalışmıyor.

  2. Ahmet Kaymaz Says:

    Cenk,

    kodları ve gerekli adımları doğru konumlandırdığından emin misin. Çünkü sayfanın masterpage içerisinde olması buna engel değil. Burada anlatıldığı gibi çalışır.

  3. Cenk Says:

    Hocam tüm adımlarınızı olduğu gibi tekrar tekrar baştan yaptım. her seferinde hep başarısız oldu. Scriptinizi bir js dosyası yapıp masterpage içinden çağırdım olmadı. açık açık yazdım yine olmadı. aspx dosyasından çağırdım olmadı. aspx dosyasında açık açık yazdım yine olmadı. denemediğim yol kalmadı. ama malesef bir türlü dediğiniz gibi çalışmıyor. keşke attach edebilsem de siz de görseydiniz.

  4. Ahmet Kaymaz Says:

    Cenk, yazmış olduğun mail adresine mail attım.

  5. Aydın Candan Says:

    Ahmet Bey Selamlar.
    Konu: postback-isleminde-aspnet-kontrolunu-disable-etmek/

    Eğer Masterpage’li sayfada validation kontrolü varsa

    function SubmitForm(Obj) fonksiyonu içerisinden ‘__doPostBack’ tanımsız hatası alıyoruz.

    Bilginize sunuyorum.
    Çok uğraştım, artık bunun bir bug olduğunu düşünüyorum.

    Siz ne dersiniz.

  6. Aydın Candan Says:

    Tamam
    Onload içine de
    this.Page.GetPostBackEventReference(this.BTN_emailsend);
    koyduğumuz zaman da, hata almıyoruz fakat postBack işlemi gerçekleşmiyor.

  7. Ahmet Kaymaz Says:

    Aydın merhaba,

    Daha önce de konuyla ilgili yapılamadığına dair mesaj geldi. İşin içerisinde javascript dolayısıyla internet tarayıcısının yeteneği olduğu için tam olarak sorunun ne olduğunu kestiremiyorum. Fakat şimdi bile ASP.NET 2.0 ortamında ve IE7 tarayıcısında aynı örneğin yaptığımda çalıştı. Ne yaptığımı adım adım anlatıyorum. Öncelikle VS.NET içerisinde Framework 2.0 altında bir ASP.NET projesi oluşturdum. Projenin içerisine bir masterpage ve bir bu materpage içerisine konumlanmış olan bir aspx sayfası oluşturdum. masterpage içerisine bir TextBox, bir Button ve bir tane RequiredFieldValidator kontrolü ekledim. Button’un OnClientClick eventini “OnClientClick=”SubmitForm(this)” şeklinde bir JavaScript yordamı olan SubmitForm() yordamına bağladım. JavaScript kodunu aşağıdaki gibi düzenledim.

    function SubmitForm(Obj){

    if (typeof(Page_ClientValidate) == 'function') {
    alert('Sayfada Validator Kontrol Var.');
    if(Page_ClientValidate()){
    alert('Validation işlemi başarılı.\nKontrol şu anda disable edilecek.');
    Obj.disabled=true;
    alert(Obj.id +' kontrolü disable edildi.');
    __doPostBack(Obj.id,'');
    }else{
    alert('Validation işlemi başarısız.');
    }
    }else{
    alert('Sayfada Validator Kontrol Yok.');
    var hdnKontrol=document.getElementsByName('Hidden1');
    hdnKontrol.item(0).setAttribute('name',Obj.getAttribute('name'));
    alert('Validation işlemi yok.\nKontrol şu anda disable edilecek.');
    Obj.disabled=true;
    alert(Obj.id +' kontrolü disable edildi.');

    Obj.form.submit();
    }

    }

    Sayfayı çalıştırıp button’u tıkladığımda ilgili alert’ler çalıştı. Hatta validation kontrolünü kaldırıp denediğimde de çalıştı.

    ‘__doPostBack’ üyesinin tanımsız olduğunu yazmışsın. ASPX sayfasının html çıktısına baktığımızda gerçekten “__doPostBack(eventTarget, eventArgument)” şeklinde bir yordam yok mu.

  8. Aydın Candan Says:

    Ahmet Bey ilginiz için teşekkür ederim.
    Öncelikle söylemek istediğim ‘__doPostBack’ hatasını almamın nedeni, benim normal buton kullanmamamdır.(userwebcontrol kullanmıştım).

    Şimdi esas konumuza dönersek aşağıdaki demoyu incelerseniz göreceksiniz ki illaki validation kontrol olduğunda yalnızca form submit oluyor. postback olmuyor.

    candan.org/….rar

  9. Ahmet Kaymaz Says:

    Mesajlarına odaklanamamışım kusura bakma. Sorunun disable veya submit değil postback işleminin gerçekleşmiyor olmasıdır. Yeri gelmişken diğer arkadaşlar için de bir özetleme yapıp sorunun neyden kaynaklandığını yazalım.

    Herhangi bir olayda postback işleminin gerçekleşmesi için istemci tarafında o kontrolün ilgili olayının (click, changed …) __doPostBack() yordamını çalıştırması gerekir. Bu yordam hangi kontrolün tıklandığını ve hangi argümanlası sunucuya göndereceğini belirler. Bu amaçla eventTarget, eventArgument parametrelerini alır. İlk parametre postback işlemine neden olmuş kontrolün adını, eventArgument ise sözkonusu kontrol ile ilişkili bilgileri, argümanları içerir. Bu iki parametrenin değeri aspx sayfasıyla birlikte otomatik olarak gelen ve hidden özelliğine sahip __EVENTTARGET, __EVENTARGUMENT kontrollerinde tutulur. Form submit olduğu zaman bu kontrollerin değerleri sunucuya gönderilir. Bundan sonraki süreç yazıda anlatıldığı gibi sunucu tarafında gerçekleşir.

    Gelelim GetPostBackEventReference yordamına; ASP.NET uygulamalarında varsayılan olarak sadece Button ve Image Button kontrolleri otomatik olarak postback işlemini sağlar. Bunların dışında TextBox veya LinkButton gibi bir kontrol aracılığıyla postback işlemi gerçekleşecekse bu kontrollerin istemci tarafında Click eventini __doPostBack() yordamını çalıştıracak şekilde düzenleme yapmamız gerekir. Yani <href=javascript:__doPostBack(‘KontrolAdi’,”)> şeklinde bir ifade yazılmalıdır. Buradaki KontrolAdi değişkeni sözkonusu kontrolün istemci tarafındaki Name bilgisidir. Bu bilgiyi her zaman kestiremeyebiliriz diye Page.GetPostBackEventReference veya Page.GetPostBackClientEvent yordamları kullanılır. ASP.NET 2.0 ile birlikte bu yordamlar yerine Page.ClientScript.GetPostBackEventReference kullanılması tavsiye edilmektedir. Bu yordam(-lar) postback işlemini tetikleyecek client tarafındaki script ifadesini döndürür. Örneğin senin örneğinde Response.Write(this.Page.GetPostBackEventReference(this.TextBox1)) kodu “__doPostBack(‘ctl00$ContentPlaceHolder1$TextBox1′,”)” ifadesini yazdırır. Yani __doPostBack yordamına $’lı ifadenin geçmesi gerekir.

    Sayfada kullandığımız bir kontrolün istemci tarafında HTML tag ifadesinin nasıl olacağı kontrolün user control, master page, panel gibi herhangi bir container içerisinde olup olmamasına bağlıdır. Örneğin sunucu tarafında ID’si Button1 olan kontrol sayfada masterpage yoksa aşağıdaki html ifadeye dönüşür.

    <input type=”submit” name=”Button1″ value=”Gönder” id=”Button1″ />

    Eğer aynı kontrol doğrudan bir master page içerisinde olursa aşağıdaki gibi değişir.

    <input type=”submit” name=”ctl00$Button1″ value=”Gönder” id=”ctl00_Button1″ />

    Aynı şekilde aynı kontrol master page içerisindeki bir sayfanın içerisinde olursa bu sefer şu şekilde değişir.

    <input type=”submit” name=”ctl00$ContentPlaceHolder1$Button1″ value=”Gönder” id=”ctl00_ContentPlaceHolder1_Button1″ />

    Buradaki id ve name bilgisi tamamen kontrolün kontrolün sunucu tarafındaki konumuna ve konteynerlerin ID bilgisine göre oluşturulur. Bir kontrolün istemci taraındaki id bilgisinin ne olduğu this.Button1.ClientID özelliğiyle, name bilgisi ise this.Button1.UniqueID ile öğrenilir.

    Bu kontrollerin postback işlemini gerçekleştirebilmesi için __doPostBack yordamına istemci tarafındaki id bilgisi değil name bilgisinin parametre olarak gönderilmesi gerekir. Oysa bizim yazdığımız JavaScript yordamında __doPostBack(Obj.id,”); şeklinde kontrolün ID’si alınmıştır. O zaman bu satırı değiştirmemiz gerekiyor. __doPostBack(Obj.name,”); şeklinde yaparsak sorun çözülmüş olacak.

    Bu arada ASP.NET 2.0 ile birlikte hem scroll konumunu korumak hem de sunucuya daha fazla bilgi göndermek için __doPostBack yordamına alternatif olarak WebForm_DoPostBackWithOptions yordamı geliştirildi. Bu yordamın parametre yapısı şu şekildedir;

    WebForm_DoPostBackWithOptions(WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit))

    Ama bu yordama dışarıdan müdahale edemiyoruz. Otomatik olarak postback kontrollerine ekleniyor. Onun için şimdilik __doPostBack yordamına devam edeceğiz. Fakat postback olmayan bir kontrolün postback kontrolü çalıştırmasını sağlayabiliriz.

    <a href=”javascript:;” onclick=” ValidateSubmit(Button1);WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("Button1", "", true, "", "", false, false))”>TIKLA ve POSTBACK ET</a>

  10. Aydın Candan Says:

    Ahmet Bey,
    İlginize tekrar teşekkür ediyorum. dediklerinizi harfiyen yerine getirip anladıktan sonra sorun yok.

    Bende işi abartıp bunlara ek olarak ‘postback durumunda ekranı disable etmek’ olayına getirdim işi. ekte sınıfın source kodları ve demo mevcut. isteyen herkes inceleyip bir fikir sahibi olabilir, geliştirebilir.

    postlarda adres vermek ne derece doğru bilmiyorum ama buradan indirebilirsiniz. http://www.candan.org/_diger/WebSite2.rar

  11. Ahmet Kaymaz Says:

    Aydın,

    örneği geliştirip custom control haline getirmiş olman çok güzel. Eline sağlık. Verdiğin link geçersiz olmadıktan sonra adres vermenin bir sakıncası yok bence.

  12. Aykut CANTÜRK Says:

    arkadaslar benim şöyle bir sorunum var
    konuyla pek alakalımı bilmiorm ama yaziim dedim
    yardımcı olursanız gerçekten çok sevinirim
    bir gridview ım var bu grid de arama sonuçlarını gösteriorm
    tıklanan ürünün id sine göre o ürüne ait detay sf sını gösteriorm
    fakat gridviewın asp kodlarında postback’ini iptal etmem gerek işi c# kod bölümünden halledicem yani
    ama o kısmı sildigim zaman hata veriyor PostBackUrl=”javascript:void(0) ” yaptığım zaman ise hiçbi işlem yapmıyor. gridview ın selectedindexchanged alanında yazdığım kodlarıda çalıştrmıyor .yani sorunum postback i silememek.
    sorunu çözemedm yardımcı olursnız sevinirim

  13. Utku Yıldırım Says:

    Merhaba Ahmet Hocam, dediğiniz şekilde obj.id yerine obj.name kullandım fakat gene postback işlemi gerçekleşmedi.Elimde bir online test modülü var cevapla butonuna 2 kere basmayı engellemek istiyorum ama bu sefer 1. sorudan 2. soruya geçemiyorum postback işlemi gerçekleşmediği için.

    Yardımcı olursanız çok sevinirim, şimdiden teşekkür ederim. İyi çalışmalar…

  14. Utku Yıldırım Says:

    Hocam, sizin alert ile verdiğiniz örnekteki scripti de denedim ama çalıştıramadım bir türlü validator kullanmadığım zaman kullanılmadı diye hata mesajı almam gerekmiyor muydu? Siz kullanmasam da çalıştı demişsiniz.

  15. Ahmet Kaymaz Says:

    Sevgili Utku,

    özellikle 9.yorumda yazdıklarıma dikkat etmeni tavsiye edeceğim. Onun dışında özel birşey yapmana gerek yok. Eğer yine de olmuyorsa IE’ın JavaScript ayarlarından kaynaklanıyor olabilir. Ayrıca JavaScript içerisinde alert ile uyarı vererek tam olarak nereye takıldığını görmek lazım.

  16. Utku Yıldırım Says:

    Cevap için teşekkürler hocam. 9. yorumdaki yazınızı dikkatle okudum ve 7. örnekteki scripti uyguladım fakat sonuç alamadım. Sayfamda validation kullanmadığım için else satırı düşüyorum ilk alertı verdikten sonra diğer alertleri vermeden bir sonraki soruya geçiyorum form submit ediliyor sanırım. Bu şekilde 1 er 1 er ilerleyebiliyorum ama işin kötü yanı ilk alerti kaldırdığımda çift tıklama ile soruyu cevaplarsam disable çalışmıyor ve 2 soru birden cevaplanıyor. Projeyi teslim etmek üzereyiz ve sırf bu yüzden tıkandık kaldık yardımlarınızı bekliyorum. Şimdiden teşekkürler.

  17. Ahmet Kaymaz Says:

    Utku örnek bir dosya göndermek için sana mail attım.

  18. Utku Yıldırım Says:

    Merhaba hocam, kusura bakmayın epeydir cevap atamadım size sorunumu hallettim sanıyordum. Bu sefer de başka bir problem çıktı. Scriptim çalışıyor fakat ie da açtığımda explorer komut dizisi hatası verdirtiyor. Açıklama olarak da form1.lnkbtn_cvp nesne değil ya da null diyor. Scriptim aşağıda, cevapla butonuna basınca bir sonraki soruya sorunsuz bir şekilde geçmesi gerekirken böyle bir hata alıyorum yardımcı olabilirseniz çok sevinirim. Teşekkürler.

    function SubmitForm(Obj) {
    form1.lnkbtn_cevap.disabled = true;
    __doPostBack(Obj.name, ”);
    alert(“Postback çalıştı”);
    }

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Giriş