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


8 × = 8

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