ASP.NET AJAX UpdatePanel Tetikleyicilerini Anlama

tarafından Scott Cate

Visual Studio'da işaretleme düzenleyicisinde çalışırken, bir UpdatePanel denetiminin iki alt öğesi olduğunu fark edebilirsiniz (IntelliSense'ten). Bunlardan biri, öğenin bulunduğu UpdatePanel denetiminin kısmi bir işlemesini tetikleyecek sayfadaki denetimleri (veya kullanıyorsanız kullanıcı denetimini) belirten Tetikleyiciler öğesidir.

Giriş

Microsoft'un ASP.NET teknolojisi nesne odaklı ve olay odaklı bir programlama modeli getirir ve bunu derlenmiş kodun avantajlarıyla bir araya getirir. Ancak, sunucu tarafı işleme modelinin teknolojinin doğasında çeşitli dezavantajları vardır ve bunların çoğu Microsoft ASP.NET 3.5 AJAX Uzantıları'ndaki yeni özelliklerle ele alınabilir. Bu uzantılar, sayfaların tam sayfa yenileme gerektirmeden kısmi olarak işlenmesi, istemci betiği (ASP.NET profil oluşturma API'si dahil) aracılığıyla Web Hizmetlerine erişme olanağı ve ASP.NET sunucu tarafı denetim kümesinde görülen denetim şemalarının çoğunu yansıtmak için tasarlanmış kapsamlı bir istemci tarafı API'si gibi birçok yeni zengin istemci özelliğini etkinleştirir.

Bu teknik inceleme, ASP.NET AJAX UpdatePanel bileşeninin XML Tetikleyicileri işlevini inceler. XML Tetikleyicileri, belirli UpdatePanel denetimleri için kısmi işlemeye neden olabilecek bileşenler üzerinde ayrıntılı denetim sağlar.

Bu teknik inceleme, .NET Framework 3.5 ve Visual Studio 2008'in Beta 2 sürümünü temel alır. Daha önce ASP.NET 2.0'ı hedefleyen bir eklenti derlemesi olan ASP.NET AJAX Uzantıları artık .NET Framework Temel Sınıf Kitaplığı ile tümleştirilmiştir. Bu teknik inceleme ayrıca Visual Web Developer Express ile değil Visual Studio 2008 ile çalışacağınızı ve Visual Studio'nun kullanıcı arabirimine göre izlenecek yollar sağlayacağınızı varsayar (ancak kod listeleri geliştirme ortamından bağımsız olarak tamamen uyumlu olacaktır).

Tetikleyiciler

Belirli bir UpdatePanel için tetikleyiciler, varsayılan olarak, (örneğin) özellikleri true olarak ayarlanmış TextBox denetimleri de dahil olmak üzere geri göndermeyi çağıran AutoPostBack tüm alt denetimleri otomatik olarak içerir. Ancak, tetikleyiciler işaretleme kullanılarak bildirim temelli olarak da eklenebilir; bu, UpdatePanel denetim bildiriminin bölümünde yapılır <triggers> . Tetikleyicilere koleksiyon özelliği aracılığıyla Triggers erişilebilir, ancak olay içinde Page_Load sayfanızın ScriptManager nesnesinin yöntemini kullanarak RegisterAsyncPostBackControl(Control) çalışma zamanında kısmi işleme tetikleyicilerini kaydetmeniz önerilir (örneğin, tasarım zamanında bir denetim yoksa). Sayfalar'ın durum bilgisi olmadığını ve bu nedenle bu denetimleri her oluşturulduğunda yeniden kaydetmeniz gerektiğini unutmayın.

Otomatik alt tetikleyici ekleme özelliği false olarak ayarlanarak ChildrenAsTriggers devre dışı bırakılabilir (böylece geri göndermeler oluşturan alt denetimler otomatik olarak kısmi işlemeleri tetiklemez). Bu, hangi belirli denetimlerin sayfa işlemeyi çağırabileceğini atama konusunda en büyük esnekliği sağlar ve bir geliştiricinin ortaya çıkabilecek olayları işlemek yerine bir olaya yanıt vermeyi kabul etmesini sağlamak için önerilir.

UpdatePanel denetimleri iç içe yerleştirildiğinde, UpdateMode Koşullu olarak ayarlandığında, alt UpdatePanel tetiklenirse, ancak üst tetiklenmediyse, yalnızca alt UpdatePanel yenilenir. Ancak üst UpdatePanel yenilenirse alt UpdatePanel de yenilenir.

<Tetikleyiciler> Öğesi

Visual Studio'da işaretleme düzenleyicisinde çalışırken, bir denetimin iki alt öğesi olduğunu fark edebilirsiniz (IntelliSense'ten UpdatePanel ). En sık görülen öğe <ContentTemplate> , temelde güncelleştirme paneli tarafından tutulacak içeriği (kısmi işlemeyi etkinleştirdiğimiz içerik) kapsülleyen öğedir. Diğer öğe, Triggers> öğesinin <Triggers> bulunduğu UpdatePanel denetiminin kısmi bir işlemesini tetikleyecek sayfadaki denetimleri (veya kullanıyorsanız kullanıcı denetimini<) belirten öğesidir.

<Triggers> öğesi iki alt düğümün her birini herhangi bir sayıda içerebilir: <asp:AsyncPostBackTrigger> ve <asp:PostBackTrigger>. Her ikisi de ve olmak üzere iki özniteliği kabul eder ControlIDEventNameve geçerli kapsülleme birimi içindeki herhangi bir Denetimi belirtebilir (örneğin, UpdatePanel denetiminiz bir Web Kullanıcı Denetimi içinde yer alıyorsa, Kullanıcı Denetiminin bulunacağı Sayfada bir Denetime başvurmayı denememelisiniz).

<asp:AsyncPostBackTrigger> öğesi, yalnızca bu tetikleyicinin alt öğe olduğu UpdatePanel'i değil, kapsülleme birimindeki herhangi bir UpdatePanel denetiminin alt öğesi olarak bulunan bir Denetimden herhangi bir olayı hedefleyebildiği için özellikle yararlıdır. Bu nedenle, kısmi sayfa güncelleştirmesini tetikleyen herhangi bir denetim yapılabilir.

Benzer şekilde, <asp:PostBackTrigger> öğesi kısmi sayfa işlemesini tetiklemede kullanılabilir, ancak sunucuya tam gidiş dönüş gerektiren bir işlemdir. Bu tetikleyici öğesi, bir denetim normalde kısmi sayfa işlemeyi tetiklediğinde (örneğin, bir UpdatePanel denetiminin öğesinde bir Button denetim mevcut olduğunda) tam sayfa işlemeyi <ContentTemplate> zorlamak için de kullanılabilir. PostBackTrigger öğesi, geçerli kapsülleme birimindeki herhangi bir UpdatePanel denetiminin alt öğesi olan herhangi bir denetimi belirtebilir.

<Tetikleyiciler> Öğe Başvurusu

İşaretlemeyi Alt Öğeler:

Tag Açıklama
<asp:AsyncPostBackTrigger> Bu tetikleyici başvuruyu içeren UpdatePanel için kısmi sayfa güncelleştirmesine neden olacak bir denetim ve olay belirtir.
<asp:PostBackTrigger> Tam sayfa güncelleştirmesine (tam sayfa yenileme) neden olacak bir denetim ve olay belirtir. Bu etiket, bir denetim kısmi işlemeyi tetiklediğinde tam yenilemeyi zorlamak için kullanılabilir.

İzlenecek yol: Cross-UpdatePanel Tetikleyicileri

  1. Kısmi işlemeyi etkinleştirmek için ScriptManager nesnesi ayarlanmış yeni bir ASP.NET sayfası oluşturun. Bu sayfaya iki UpdatePanel ekleyin- ilkinde bir Etiket denetimi ( Etiket1 ) ve iki Düğme denetimi ( Düğme1 ve Düğme2 ) ekleyin. Button1 her ikisini de güncelleştirmek için tıklayın ve Düğme2 ifadesinin Bunu Güncelleştirmek için Tıklayın veya bu satırlar boyunca bir şey demesi gerekir. İkinci UpdatePanel'de yalnızca bir Etiket denetimi ( Etiket2 ) ekleyin, ancak foreColor özelliğini, ayırt etmek için varsayılan dışında bir değere ayarlayın.
  2. Her iki UpdatePanel etiketinin UpdateMode özelliğini Koşullu olarak ayarlayın.

Liste 1: default.aspx için işaretleme:



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
   <head runat="server">
      <title>Untitled Page</title>
   </head>
   <body>
      <form id="form1" runat="server">
         <asp:ScriptManager EnablePartialRendering="true"
            ID="ScriptManager1" runat="server"></asp:ScriptManager>
         <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label1" runat="server" />
                  <br />
                  <asp:Button ID="Button1" runat="server"
                     Text="Update Both Panels" OnClick="Button1_Click" />
                  <asp:Button ID="Button2" runat="server"
                     Text="Update This Panel" OnClick="Button2_Click" />
               </ContentTemplate>
            </asp:UpdatePanel>
            <asp:UpdatePanel ID="UpdatePanel2" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label2" runat="server" ForeColor="red" />
               </ContentTemplate>
               <Triggers>
                  <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
               </Triggers>
            </asp:UpdatePanel>
         </div>
      </form>
   </body>
</html>

  1. Button1 için Click olay işleyicisinde Label1.Text ve Label2.Text değerlerini zamana bağlı bir değere (DateTime.Now.ToLongTimeString() gibi) ayarlayın. Button2 için Click olay işleyicisi için yalnızca Label1.Text değerini zamana bağlı değer olarak ayarlayın.

Listeleme 2: default.aspx.cs dosyasında codebehind (kırpılmış):

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
        Label2.Text = DateTime.Now.ToLongTimeString();
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }
}
  1. Projeyi derlemek ve çalıştırmak için F5 tuşuna basın. Her İki Paneli Güncelleştir'e tıkladığınızda her iki etiketin de metni değiştirdiğini unutmayın; ancak Bu Paneli Güncelleştir'e tıkladığınızda yalnızca Etiket1 güncelleştirilir.

Her İki Paneli Güncelleştir ifadesinin gösterildiği ilk düğmeyi ve Bu Paneli Güncelleştir'i belirten ikinci düğmeyi gösteren ekran görüntüsü.

(Tam boyutlu görüntüyü görüntülemek için tıklayın)

Kaputun Altında

Az önce oluşturacağımız örneği kullanarak AJAX'ın ne ASP.NET ve UpdatePanel çapraz panel tetikleyicilerimizin nasıl çalıştığına göz atabiliriz. Bunu yapmak için, oluşturulan sayfa kaynağı HTML'sinin yanı sıra FireBug adlı Mozilla Firefox uzantısıyla çalışacağız - bununla, AJAX geri göndermelerini kolayca inceleyebiliriz. Lutz Roeder tarafından kullanılan .NET Reflector aracını da kullanacağız. Bu araçların her ikisi de çevrimiçi olarak serbestçe kullanılabilir ve bir internet araması ile bulunabilir.

Sayfa kaynak kodunun incelenmesi sıradan dışında neredeyse hiçbir şey göstermez; UpdatePanel denetimleri kapsayıcı olarak <div> işlenir ve betik kaynağının tarafından sağlanan içerdiğini <asp:ScriptManager>görebiliriz. Ayrıca AJAX istemci betik kitaplığının içinde bulunan PageRequestManager'a AJAX'a özgü bazı yeni çağrılar da vardır. Son olarak iki UpdatePanel kapsayıcısını görüyoruz: biri kapsayıcı olarak <span> işlenen <input> iki <asp:Label> denetime sahip işlenmiş düğmelere sahip. (FireBug'da DOM ağacını incelerseniz, etiketlerin görünür içerik üretmediklerini belirtmek için soluk görüntülendiğini fark edeceksiniz).

Bu Paneli Güncelleştir düğmesine tıklayın ve en üstteki UpdatePanel'in geçerli sunucu saatiyle güncelleştirileceğini göreceksiniz. FireBug'da, isteği inceleyebilmeniz için Konsol sekmesini seçin. Önce POST isteği parametrelerini inceleyin:

Konsol'un seçili olduğu bir Firebug iletişim kutusunu gösteren ekran görüntüsü.

(Tam boyutlu görüntüyü görüntülemek için tıklayın)

UpdatePanel'in sunucu tarafı AJAX koduna tam olarak hangi denetim ağacının denetimin ScriptManager1 parametresiyle Button1 tetiklendiğini belirttiğini UpdatePanel1 unutmayın. Şimdi Her İki Paneli De Güncelleştir düğmesine tıklayın. Ardından yanıtı incelediğimizde, bir dizede ayarlanmış, kanalla ayrılmış bir dizi değişken görüyoruz; özellikle, tarayıcıya gönderilen HTML'sinin tamamının en üstteki UpdatePanel UpdatePanel1olan öğesini görüyoruz. AJAX istemci betik kitaplığı, UpdatePanel'in özgün HTML içeriğini özelliği aracılığıyla .innerHTML yeni içerikle değiştirir ve bu nedenle sunucu değiştirilen içeriği sunucudan HTML olarak gönderir.

Şimdi Her İki Paneli De Güncelleştir düğmesine tıklayın ve sunucudan sonuçları inceleyin. Sonuçlar çok benzerdir; her iki UpdatePanel de sunucudan yeni HTML alır. Önceki geri çağırmada olduğu gibi ek sayfa durumu gönderilir.

Gördüğümüz gibi, AJAX geri gönderme gerçekleştirmek için özel kod kullanılmadığından, AJAX istemci betik kitaplığı ek kod olmadan form geri göndermelerini kesebilir. Sunucu denetimleri, formu otomatik olarak göndermemeleri için JavaScript'i otomatik olarak kullanır. ASP.NET, öncelikle otomatik betik kaynak ekleme, PostBackOptions sınıfı ve ClientScriptManager sınıfı tarafından elde edilen form doğrulama ve durum için otomatik olarak kod ekler.

Örneğin, bir CheckBox denetimi düşünün; .NET Reflector'da sınıf ayrıştırma işlemini inceleyin. Bunu yapmak için System.Web derlemenizin açık olduğundan emin olun ve yöntemini açarak sınıfına RenderInputTag gidinSystem.Web.UI.WebControls.CheckBox. Özelliğini denetleen AutoPostBack bir koşullu arama yapın:

Tıklama eşittir'de ile başlayan kodu gösteren ekran görüntüsü.

(Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bir denetimde CheckBox otomatik geri gönderme etkinleştirildiğinde (AutoPostBack özelliğinin true olması yoluyla), sonuç <input> etiketi bu nedenle özniteliğinde onclick ASP.NET olay işleme betiğiyle işlenir. Formun gönderiminin kesilmesi, ASP.NET AJAX'ın sayfaya müdahalesiz olarak eklenmesine olanak tanır ve büyük olasılıkla kesin olmayan bir dize değiştirmesi kullanarak oluşabilecek olası hataya neden olan değişiklikleri önlemeye yardımcı olur. Ayrıca bu, herhangi bir özel ASP.NET denetiminin bir UpdatePanel kapsayıcısı içinde kullanımını destekleyecek ek kod olmadan ASP.NET AJAX'ın gücünü kullanmasını sağlar.

İşlevsellik, <triggers> _updateControls PageRequestManager çağrısında başlatılan değerlere karşılık gelir (ASP.NET AJAX istemci betik kitaplığının, alt çizgiyle başlayan yöntemlerin, olayların ve alan adlarının iç olarak işaretlenmesi ve kitaplığın dışında kullanılmak üzere tasarlanmaması kuralını kullandığını unutmayın). Bununla, hangi denetimlerin AJAX geri göndermelerine neden olduğunu gözlemleyebiliriz.

Örneğin, sayfaya iki ek denetim daha ekleyelim. Bu denetimlerden biri UpdatePanels'in dışında, diğeri de UpdatePanel'in içinde bırakılarak elde edilebilir. Üst UpdatePanel içine bir CheckBox denetimi ekleyecek ve listede tanımlanmış bir dizi renk içeren bir DropDownList bırakacağız. İşte yeni işaretleme:

Liste 3: Yeni İşaretlemeyi

<%@ Page Language="C#" AutoEventWireup="true"
 CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
 <head id="Head1" runat="server">
 <title>Untitled Page</title>
 </head>
 <body>
 <form id="form1" runat="server">
 <asp:ScriptManager EnablePartialRendering="true"
 ID="ScriptManager1" runat="server"></asp:ScriptManager>
 <div>
 <asp:UpdatePanel ID="UpdatePanel1" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label1" runat="server" /><br />
 <asp:Button ID="Button1" runat="server"
 Text="Update Both Panels" OnClick="Button1_Click" />
 <asp:Button ID="Button2" runat="server"
 Text="Update This Panel" OnClick="Button2_Click" />
 <asp:CheckBox ID="cbDate" runat="server"
 Text="Include Date" AutoPostBack="false"
 OnCheckedChanged="cbDate_CheckedChanged" />
 </ContentTemplate>
 </asp:UpdatePanel>
 <asp:UpdatePanel ID="UpdatePanel2" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label2" runat="server"
 ForeColor="red" />
 </ContentTemplate>
 <Triggers>
 <asp:AsyncPostBackTrigger ControlID="Button1" 
 EventName="Click" />
 <asp:AsyncPostBackTrigger ControlID="ddlColor" 
 EventName="SelectedIndexChanged" />
 </Triggers>
 </asp:UpdatePanel>
 <asp:DropDownList ID="ddlColor" runat="server"
 AutoPostBack="true"
 OnSelectedIndexChanged="ddlColor_SelectedIndexChanged">
 <asp:ListItem Selected="true" Value="Red" />
 <asp:ListItem Value="Blue" />
 <asp:ListItem Value="Green" />
 </asp:DropDownList>
 </div>
 </form>
 </body>
</html>

İşte yeni arka planda kod:

Listeleme 4: Codebehind

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
            Label2.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
            Label2.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void cbDate_CheckedChanged(object sender, EventArgs e)
    {
        cbDate.Font.Bold = cbDate.Checked;
    }
    protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
    {
        Color c = Color.FromName(ddlColor.SelectedValue);
        Label2.ForeColor = c;
    }
}

Bu sayfanın ardındaki fikir, açılan listenin ikinci etiketi göstermek için üç renkten birini seçmesi, onay kutusunun hem kalın olup olmadığını hem de etiketlerin tarihi ve saati görüntüleyip görüntülemediğini belirlemesidir. Onay kutusu bir AJAX güncelleştirmesine neden olmamalıdır, ancak açılan liste bir UpdatePanel içinde barındırılmasa bile olmalıdır.

Adsız Sayfa adlı bir web tarayıcısının ve Her İki Paneli Güncelleştir düğmesinin altında Mavi rengin seçili olduğu bir açılan listeyi gösteren ekran görüntüsü.

(Tam boyutlu görüntüyü görüntülemek için tıklayın)

Yukarıdaki ekran görüntüsünde göründüğü gibi, tıklanacak en son düğme sağ düğmeydi Bu Paneli Güncelleştir, en üstteki zamanı en alttan bağımsız olarak güncelleştirdi. Tarih, alttaki etikette göründüğünden tıklamalar arasında da kapatıldı. Son olarak, alttaki etiketin rengi ilgi çekicidir: Denetim durumunun önemli olduğunu gösteren etiket metninden daha yakın zamanda güncelleştirilmiştir ve kullanıcılar AJAX geri göndermeleri aracılığıyla korunmasını bekler. Ancak, saat güncelleştirilmedi. Denetim sunucuda yeniden işlenirken ASP.NET çalışma zamanı tarafından yorumlanan sayfanın __VIEWSTATE alanının kalıcılığı aracılığıyla saat otomatik olarak yeniden dolduruldu. ASP.NET AJAX sunucu kodu, denetimlerin durumunu hangi yöntemlerle değiştirdiğini tanımaz; yalnızca görünüm durumundan yeniden doldurulur ve uygun olayları çalıştırır.

Bununla birlikte, Page_Load olayı içinde saati başlatmış olsaydım, zaman doğru şekilde artırılırdı. Sonuç olarak, geliştiriciler uygun olay işleyicileri sırasında uygun kodun çalıştırılmasına karşı temsilci olmalı ve bir denetim olay işleyicisi uygun olduğunda Page_Load kullanımından kaçınmalıdır.

Özet

ASP.NET AJAX Uzantıları UpdatePanel denetimi çok yönlüdür ve güncelleştirilmesi gereken denetim olaylarını tanımlamak için bir dizi yöntem kullanabilir. Alt denetimleri tarafından otomatik olarak güncelleştirilir, ancak sayfanın başka bir yerindeki denetim olaylarına da yanıt verebilir.

Sunucu işleme yükünün potansiyelini azaltmak için, bir UpdatePanel özelliğinin olarak falseayarlanması ve olayların varsayılan olarak dahil etmek yerine kabul edilmesi önerilirChildrenAsTriggers. Bu ayrıca, gerekmeyen olayların doğrulama ve giriş alanlarında yapılan değişiklikler de dahil olmak üzere istenmeyebilecek etkilere neden olmasını önler. Bu tür hataları yalıtmak zor olabilir, çünkü sayfa kullanıcıya saydam olarak güncelleştirilir ve bu nedenle nedeni hemen belirgin olmayabilir.

ASP.NET AJAX form kesme sonrası modelinin iç çalışmalarını inceleyerek, ASP.NET tarafından önceden sağlanan çerçeveyi kullandığını saptayabildik. Bunu yaparken, aynı çerçeve kullanılarak tasarlanan denetimlerle en yüksek uyumluluğu korur ve sayfa için yazılmış ek JavaScript'lere minimum düzeyde müdahale eder.

Biyografi

Rob Paveza, Tempe, AZ'nin önde gelen etkileşimli pazarlama firması Terralever'da (www.terralever.com) üst düzey bir .NET uygulama geliştiricisi. Adresinden ulaşılabiliyor robpaveza@gmail.comve blogu adresinde http://geekswithblogs.net/robp/bulunuyor.

Scott Cate, 1997'den beri Microsoft Web teknolojileriyle çalışmaktadır ve Bilgi Bankası Yazılımı çözümlerine odaklanan ASP.NET tabanlı uygulamalar yazma konusunda uzmanlaştığı myKB.com (www.myKB.com) Başkanıdır. Scott'a ScottCate.com adresinden scott.cate@myKB.com veya blogundan e-posta yoluyla ulaşabilirsiniz .