Eski bir WebForms uygulamasına küçük bir veri çağrısı eklerken bütün sayfayı JSON'a çevirmek gerekmiyor. ASMX WebMethod, dar bir veri sözleşmesi açmak için kullanılabiliyor. Burada önemli olan yalnız metoda öznitelik eklemek değil; kimlik, girdi, yanıt ve hata davranışını sayfanın görünüm durumundan ayırmak.
İki alanlı bir lookup sözleşmesi
Arşivimdeki WebForms portal ve veri yardımcıları bu yaklaşımın bağlamı. Örnek, .NET Framework ve System.Web servis altyapısına ait. Modern ASP.NET Core endpoint'i gibi çalıştırılmaz. LookupReply içinde yalnız Id ve Title var; ViewState, kontrol ağacı veya veritabanı entity'si yanıtın parçası değil.
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Security;
[ScriptService]
public class LookupService : WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat=ResponseFormat.Json)]
public LookupReply GetItem(int id)
{
if(Context.User.Identity == null || !Context.User.Identity.IsAuthenticated)
throw new SecurityException("Authentication required");
if(id!=1) throw new ArgumentException("Unknown item");
return new LookupReply { Id=1, Title="Demo" };
}
}
public class LookupReply { public int Id {get;set;} public string Title {get;set;} }
ScriptService sınıfı istemci betiklerinden kullanılabilen bir servis olarak işaretliyor. WebMethod operasyonu açıyor; ScriptMethod yanıt biçimi beklentisini belirtiyor. .asmx dosyasının servis sınıfına bağlanması ve host yapılandırması ayrıca gerekir. Bu sınıfı derlemek, endpoint'in belirli bir adreste ayağa kalktığını tek başına göstermez.
ASMX metodu ile sayfa metodu ayrımı
Bu örnek WebService türeten bir ASMX servis sınıfı. Bir .aspx sayfası içindeki static WebMethod/PageMethods yaklaşımıyla aynı barındırma modeli değildir. İstemci URL'si, yöntem çağrısı ve bağlam erişimi seçilen modele göre değişir. “WebMethod var, her sayfa metodu aynı şekilde çağrılır” varsayımı eski sistemlerde tanıyı zorlaştırır.
JSON yanıtının ASP.NET sürüm ve çağrı biçimine göre d sarmalayıcısı içermesi de istemcide kontrol edilmelidir. Bir örnekte görülen response.d kullanımını başka bir endpoint'e körlemesine taşımam; gerçek yanıtı sözleşmeyle karşılaştırırım. İstemci yalnız JSON dönüyor diye başarılı işlem kabul etmemeli.
Kimlik kontrolünü sayfa düğmesine bırakmamak
Context.User üzerinden kimliğin doğrulanması sunucuda yapılıyor. Ekrandaki düğmenin görünür olması veya JavaScript'te isAdmin tutulması bu kontrolün yerine geçmez. Gerçek sistemde kimlik doğrulama modülü ve servis yapılandırması aynı oturum bilgisini taşımalı. Varsayılan session davranışı da ihtiyaç halinde ayrıca incelenir; her WebMethod'un sayfa session'ını aynı biçimde kullandığını varsaymam.
Kimlik doğrulamasından sonra kaynak yetkisi gelir. Örnekte yalnız id=1 kabul ediliyor; gerçek lookup metodu Id üzerinden yetkili veri kapsamını sorgulamalı. “Kullanıcı giriş yapmış” koşulu, istediği her kaydı okumaya izin vermez. SQL kurulacaksa parametreli sorgu kullanılır; id'nin URL'den gelmesi güvenilir olduğu anlamına gelmez.
Exception atmak, HTTP sözleşmesini tamamlamaz
SecurityException ve ArgumentException burada reddedilen dalları görünür kılıyor. ASMX host'un bunları istemciye hangi HTTP kodu ve gövdeyle aktardığı ayrıca ele alınmalıdır; bu kodun kendiliğinden modern bir 401/400 zarfı ürettiğini iddia etmiyorum. Üretimde iç stack trace ve ayrıntılı hata metni sızdırılmadan tutarlı bir hata eşlemesi yapılır.
Veri değiştiren operasyon eklenecekse yalnız JSON kullanmak CSRF savunması değildir. Cookie tabanlı kimlikte yazma istekleri için sunucu tarafı koruma gerekir. Salt lookup ile kayıt komutunu aynı GET çağrısında birleştirmek de önbellek ve tekrar çağrı davranışını bozabilir.
Mevcut sistemi adım adım iyileştirmek
Dar DTO ve servis katmanına delegasyon, tüm uygulamayı yeniden yazmadan sözleşmeyi anlaşılır hale getirebilir. Taşıma katmanı değiştiğinde de aynı iş kararları yeniden kullanılabilir. Kontrolde oturumsuz çağrı, yetkisiz Id, bulunamayan kayıt ve doğru yanıtı ayrı denerim. Geliştirme ortamında çalışan bir çağrının üretimde de aynı auth modülü, yol ve JSON biçimiyle geldiğini görmek gerekir.