ASP.NET'te Session Based Output Caching

0 dakikada yazıldı

44564 defa okundu

Düzenle

ASP.NET'te OutputCaching olayını bilmeyen yoktur diye tahmin ediyorum. Kabaca herhangi bir sayfanın çıktısının cache'e alınmasını sağlayan bu özellik ile isterseniz PartialCaching de yapabilirsiniz. Yani bir sayfanın tamamı cache'e alınmazken içindeki bir UserControl alınabilir. Tüm bunların epey detaylıca ayarlarını yapmak da mümkün. Örneğin Cache'in ne şekilde oluşturulacağını belirlemek için VaryByParam ile GET/POST ile gelen parametrelerdeki değişiklikleri baz alabiliyoruz. Buna ek olarak VaryByControl ile de sayfadaki herhangi bir ASP.NET kontrolündeki değişikliğin Cache'i valide etmesini de sağlayabiliyoruz. Böylece tek bir sayfa URL'den gelen bir ID'ye göre birden çok defa cache'e alınabiliyor veya sayfadaki bir kontroldeki her state için ayrı ayrı cache'lenebiliyor.

VaryByCustom

İşte şimdi size bir VaryByCustom hikayesi anlatacağım :) Çoğumuzun bilmediğini tahmin ettiğim VaryByCustom aynı VaryByParam ve VaryByControl'de olduğu gibi OutputCaching'de variyasyonların nasıl yaratılacağını belirliyor. Fakat adından da anlaşılacağı üzere bu işlemi olabildiğince özelleştirilebilir bir şekilde yaparak bize esneklik sağlıyor. Esasında benim tüm bu makaleyi yazmama neden olan ihtiyaç şöyle bir ihtiyaçtı. ASP.NET'te bir sayfada yer alan UserControl'üm dışarıdan aldığı bir parametreye göre içerik gösteriyor. Bu parametre hep değişebiliyor ve tabi ki farklı parametreler için farklı cache'ler şart. Bu noktaya kadar sanırım "VaryByControl" yeter de artar. UserControl'ün içinde dışarıdan parametreyi aldığı bir property var ve bu Property'yi VaryByControl ile OutputCache'e vermemiz bu noktaya kadar ihtiyacımızı giderecek.

[ASP.NET]

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ornek.ascx.vb" Inherits="site.ornek" %>
<%@ OutputCache Duration="160" VaryByControl="ornek.birID" Shared="true" %>

Yukarıdaki manzarada 160 saniyelik bir OutputCache'i UserControl'e verdik. Farklı sayfalarda bu UserControl aynı parametrelerle kullanılırsa tek bir defa Cache'lenmesi için Shared özelliğini de True olarak set ettik. Son olarak da ornek adındaki UserControlümüzün birID adındaki Property'sini VaryByControl diyerek tüm cache'lerin bu property'ye gelen değerler etrafında oluşturulmasını sağladık. Bir sonraki adıma geçecek olursak esas ilginç noktaya gelmiş olacağız. Tüm cachle'lerin session based olmasını istiyoruz :) Evet, bir nefes alalım... Biliyorsunuz ASP.NET'teki OutputCache Session based değil. Yani bir kullanıcı siteye gelip Cache'lenmeye sebep oldu ise diğer kullanıcı geldiğinde Cachelenmiş içeriği görür. Aslında bu tam da OutputCache'in yapması gereken şey. Ama benim ihtiyacım olan bu değildi :) İstediğim şey siteye gelen her kullanıcının kendi cache'ine sahip olması. Böylece her kullanıcı siteye geldiği anda taze veri alacak ve kendi session'ı boyunca cachelenmiş veri görecek. Bunu yapabilmek için VaryBySession gibi bir şey lazım ki böyle bir şey yok. O yüzden ben de VaryByCustom'a başvurma kararı aldım.

[ASP.NET]

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ornek.ascx.vb" Inherits="site.ornek" %>
<%@ OutputCache Duration="160" VaryByControl="ornek.birID" VaryByCustom="sessionlifetime" Shared="true" %>

İlk olarak yukarıdaki gibi OutputCache'e VaryByCustom özelliği veriyoruz. Buraya ne yazdığınız önemli değil. Yeter ki Browser yazmayın :) çünkü o şekilde tanımlı hazır bir yapı zaten var. Onun yerine ben kendi örneğimde "sessionlifetime" dedim. Dediğim gibi buraya herhangi bir string değer verebilirsiniz. Bir sonraki adımda bu değeri yakalayan yine biz olacağız.

[Global.asax / VB]

Public Overrides Function GetVaryByCustomString(context As HttpContext, arg As String) As String
    If (arg = "sessionlifetime") Then
        Return context.Session.SessionID
    Else
        Return ""
    End If
End Function

Global.asax içerisinde Override edebileceğiniz GetVaryByCustomString adında bir fonksiyon var. Bu arkadaşa context olarak HttpContext ile beraber bir de args parametresi geliyor. Koddan da anlayabileceğiniz üzere args zaten bizim VaryByCustom'a verdiğimiz değer. Eğer farklı sayfalarda farklı VaryByCustom değerleriniz varsa buradaki fonksiyonu bir Switch koyarak ilerlemeniz gerekecek. Ben Session based caching istediğim için Cache Validasyonu adına SessionID'yi kullanmak mantıklı oldu. Buradan geri döndüğünüz her farklı değer OutputCache için bir input olacak ve eğer yeni farklı bir değer gelmiş ise hemen yeni bir Cache yaratılacak. Eğer değer daha önce geri gönderilmiş ise bu sefer söz konusu kontrolün içeriği Cache'den stream edilecek.

İşte bu kadar basit. Böylece hem UserControl'e gelen parametreye göre hem de Session based bir OutputCaching'im olmuş oldu :) Ben mutluyum, umarım sizin de işinize yarar.

Kolay gelsin.