Sayfalar

30 Ağustos 2012 Perşembe

AJAX PageMethods nedir?

ASP.NET üzerindeki PageMethods yapısı temelde istemci tarafından sunucu sunucu kodlarının çağırmamızı sağlayan ASMX web servislerine alternatif bir yapıdır. Bu yapıyı ASMX web servislerinden ayıran göze çarpan yapısal farklarından biri, web servislerinde servis örnekleri GET/POST HTTP Requestleri atıldıkça oluşturulmasına karşı PageMethods yapısında Application örneklendiği anda sayfanın adresinde oluşan bir servis yapısı olması ve sadece HTTP POST Request'ine cevap vermesidir.

ASMX web servislerinde yazılacak olan metotların [WebService] attribute'unu taşıyan bir ASMX üzerine non-statik olarak yazılmasına karşın PageMethod'lar bu attribute'u taşımasına gerek olmayan ASPX üzerine statik olarak yazılır. PageMethod'ların sağlaması gereken 2 şart vardır:
  1. static ile deklare edilen static bir metot olmalı
  2. [WebMethod] attribute'unu üzerine almalı
Örneğin GetString() adında bir method Default.aspx sayfasının üzerinde aşağıdaki şekilde tanımlanır:

public partial class _Default : Page 
{
    [WebMethod]
    public static string GetString()
    {
        return "Merhaba Televole";
    }
}

Sunucu metodu istemci tarafından nasıl çağrılır?

Bunu çağırmak için en kolay yöntem sayfaya bir ScriptManager ekleyip bunun ürettiği kodları çağırmak. Sayfaya eklenen ScriptManager kontrolünün üzerindeki EnablePageMethods özelliği aktifleştirildiğinde bu kontrol sayfada PageMethods adında bir javascript proxy nesnesi üretir ve sayfadaki tüm metotlar için bu proxy nesnesinde metotlar oluşturur. Üstteki koda karşılık aşağıdaki proxy oluşturulur:

var PageMethods = function() {
    PageMethods.initializeBase(this);
    this._timeout = 0;
    this._userContext = null;
    this._succeeded = null;
    this._failed = null;
}
 
PageMethods.prototype = {
   _get_path:function() {
       var p = this.get_path();
       if (p) return p;
       else return PageMethods._staticInstance.get_path();},
   GetString:function(succeededCallback, failedCallback, userContext) {
       return this._invoke(this._get_path(), 'GetString',false,{},
              succeededCallback,failedCallback,userContext); }}
PageMethods.registerClass('PageMethods',Sys.Net.WebServiceProxy);
PageMethods._staticInstance = new PageMethods();
 
// Generic initialization code omitted for brevity.

PageMethods.set_path("/Default.aspx");
PageMethods.GetString = function(onSuccess,onFailed,userContext) {
    PageMethods._staticInstance.GetString(onSuccess,onFailed,userContext);
}

Bu kodun ne yaptığını anlamamız gerekmiyor. JavaScript ile bu proxy üzerindeki metodu çağırdığımızda arka tarafta otomatik bir servis çağrısı yapar ve sunucu tarafındaki Kod tetiklenir.

$(document).ready(function() { 
    PageMethods.GetString(function onSucceed(msg) {
        alert(msg);
    });
});

Bu otomatizasyonun sonucu olarak sayfadaki pagemethod'ların sayısı arttıkça üretilecek olan bu proxy kodunun da boyutu artar. Sayfa üzerine dinamik olarak basıldığından cache'lenmesi mümkün olmayan bu yazı öbeği yüzünden veri trafiği olumsuz yönde etkilenir.

 

Bu metotlar ScriptManager kullanmadan çağrılamaz mı?

Neyseki burada imdadımıza PageMethods'un esnek mimarisi yetişir. Sayfalardaki uzun proxy kodları oluşturan ScriptManager kontrolünü kullanmadan bu metotları tetiklemek de mümkündür. Bunun için jQuery gibi bir scripting diliyle servis çağrısını manuel olarak yapabiliriz. Böylece sayfadaki metotları çağıracak olan jQuery kodlarını ayrı bir .js dosyasına yazarak cache'lenmesini sağlayabilir ve gereksiz veri trafiğinin önüne geçmiş oluruz.

Bu çağrıyı yapabilmek için ASMX webservisine yaptığımız çağrının benzerini yapabiliriz.
  • İstek HTTP POST olmalı
  • İsteğin content-type parametresi "application/json; charset=utf-8" olmalı
Böylece kodumuzu aşağıdaki şekilde bir .js dosyasına yazıp sayfaya include ederek tüm problemlerimizi çözebiliriz.

$.ajax({
    type: "POST",
    url: "/Default.aspx/GetString",
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
        alert(msg.d);
    }
});

Hiç yorum yok:

Yorum Gönder