8 Temmuz 2011 Cuma

Sharepoint CSS Cache Problemi

Sharepoint safyalarımızda css stil dosyaları kullanıyoruz sıklıkla. Çalıştığım projede geçenlerde başıma gelen bir problemde, sunucudaki css dosyalarını güncellememe rağmen, portala istekte bulunan makinede eski css stiline sahip görünüm geliyordu. Sadece tarayıcının cookie, geçici internet dosyaları, geçmişi vs. silip, tekrar portal'a istekte bulunduğumda yeni stil dosyasını aldığını fark ettim. Yaptığım ufak araştırmada sorunun kaynağının, sayfa yükleme hızı artsın diye kullanılan "Css Caching" mekanizması olduğunu öğrendim. Bu yazımda da bulduğum çözümler arasında "best practice" sayılanı sizinle paylaşacağım.

Çözüm aslında çok basit bir mantığa dayanıyor. aspx sayfasının başına eklediğimiz css dosyalarının sonuna her çağrımızda farklı bir parametre (versiyonlama mantığı) ekliyoruz. Bu parametre ne olabilir? Random bir karakter dizisi olabilir, o anki tarih verisi olabilir vs.. Benim bulduğum çözümde random karakter dizisi üzerinden gittiği için ben de aynısını uygulamdım örnekte.

Öncelikle Sharepoint projemizde "CssInjector" adında bir tane user control yaratıyoruz ve Render metodunu override ediyoruz.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Text;

namespace TyAppPage.UserControls.TyAppPage
{
public partial class CssInjector : UserControl
{
private const string CSS_LINK_FORMAT = @"<link rel=""stylesheet"" type=""text/css"" href=""{0}"">";

private string _CSSFileLink;
public string CSSFileLink
{
get { return _CSSFileLink; }
set { _CSSFileLink = value; }
}

protected override void Render(HtmlTextWriter writer)
{
if (this.CSSFileLink.Length > 0)
{
writer.Write(string.Format(CSS_LINK_FORMAT, this.CSSFileLink + "?k=" + GetUniqueKey(8)));
}
}

// Random veri üreten metot
private static string GetUniqueKey(int length)
{
char[] chars = new char[62];
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
StringBuilder result = new StringBuilder(length);
Random rnd = new Random();

for (int i = 0; i < length; i++)
{
result.Append(chars[rnd.Next(chars.Length)]);
}

return result.ToString();
}
}
}
GetUniqueKey isimli metodumuzla çok basit bir şekilde random veri dizisi üretip, css çağrı linkimizin sonuna parametre olarak ekliyoruz. Bu mantıkla her seferinde farklı bir karakter dizisi içeren parametre üretileceği için her seferinde stil dosyasının güncel halini alacak tarayıcı.

Geriye kalan tek şey de yarattığımız user control'ümüzü sharepoint master page'imizde ya da stil dosyasının kullanılacağı aspx dosyasının ilgili yerine bağlantı olarak eklemek. Bunun için önce sayfanın başında kontrolü register ediyoruz.
<%@ Register TagPrefix="CustomUserControls" TagName="cssInjectorControl" Src="~/_controltemplates/TyAppPage/CssInjector.ascx" %>
Sayfanın tepesinde register ettiğimiz kontrolü, content içerisinde aşağıdaki gibi kullanıyoruz.
<CustomUserControls:cssInjectorControl runat="server" ID="cssInjector" CSSFileLink="/_layouts/SoftTech/Ty/Styles/default.css" />

Gerisi zaten standart kullanım.. İstediğimiz kontrole css içerisinde istediğimiz etiketi verebiliriz.

<asp:Label ID="lbl_Baslik" CssClass="baslik" runat="server"></asp:Label>
İşte bu kadar! Bundan sonra Sharepoint sunucusuna yeni bir css dosyası deploy ettiğimizde, istemcideki tarayıcılar anında değişikliği algılayabilecek.

Kolay gelsin ;)

P.S. Çözüm araştırmaları sırasında yararlandığım güzel post burda.

Hiç yorum yok: