۱۳۸۸/۱۰/۲۱

كش كردن اطلاعات غير پويا در ASP.Net - قسمت چهارم


قسمت‌هاي اول تا سوم اين مقاله: + و + و +

در قسمت چهارم قصد داريم هدر مربوط به Content Expiration Date را توسط يك Http module به محتواي غيرپوياي سايت مانند تصاوير ، فايل‌هاي CSS و غيره اعمال كنيم. اين روش از روش قسمت دوم ساده‌تر است و جامع‌تر.
ابتدا يك پروژه‌ي Class library جديد را به نام StaticContentCacheModule ايجاد كرده و سپس ارجاعي را به اسمبلي استاندارد System.Web.dll به آن خواهيم افزود. سپس كدهاي مرتبط با اين ماژول به شرح زير هستند:

//StaticCache .cs
using System;
using System.Web;

namespace StaticContentCacheModule
{
public class StaticCache : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += context_PreSendRequestHeaders;
}

static void context_PreSendRequestHeaders(object sender, EventArgs e)
{
//capture the current Response
var currentResponse = ((HttpApplication)sender).Response;

if (CacheManager.ShouldCache(currentResponse.ContentType))
{
currentResponse.AddHeader("cache-control", "public");
currentResponse.AddHeader("Expires", DateTime.Now.Add(TimeSpan.FromDays(30)).ToString());
}
}

public void Dispose() { }
}
}

در اينجا ContentType تك تك عناصري كه توسط وب سرور ارائه خواهند شد، بررسي مي‌شود. اگر نيازي به كش شدن آن‌ها وجود داشت (توسط كلاس CacheManager اين امر مشخص مي‌گردد)، هدر مربوطه اضافه مي‌گردد.

//CacheManager.cs
using System;

namespace StaticContentCacheModule
{
class CacheManager
{
public static bool ShouldCache(string contentType)
{
contentType = contentType.ToLower();
string[] parts =
contentType.Split(
new[] { ';' },
StringSplitOptions.RemoveEmptyEntries
);

if (parts.Length > 0)
contentType = parts[0];

bool cache = false;

switch (contentType)
{
case "text/css":
cache = true; break;
case "text/javascript":
case "text/jscript":
cache = true; break;
case "image/jpeg":
cache = true; break;
case "image/gif":
cache = true; break;
case "application/octet-stream":
cache = true; break;
default:
{
if (contentType.Contains("javascript"))
cache = true;
if (contentType.Contains("css"))
cache = true;
if (contentType.Contains("image"))
cache = true;
if (contentType.Contains("application"))
cache = true;
}
break;
}

return cache;
}
}
}

در اين كلاس، contentType دريافتي بررسي مي‌شود. اگر نوع محتواي قابل ارائه از نوع CSS ، JavaScript ، تصوير و يا Application بود، يك مقدار true بازگشت داده خواهد شد.
نهايتا براي استفاده از اين Http module جديد در IIS6 به قبل در وب كانفيگ برنامه خواهيم داشت:

<httpModules>
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
</httpModules>

و يا در IIS7 اين تغييرات به صورت زير مي‌تواند باشد:

<system.webServer>
<modules>
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
</modules>

اكنون اگر يك پروژه‌ي آزمايشي جديد ASP.Net را گشوده و فايل css ساده‌اي را به آن اضافه كنيم، بررسي هدر نهايي توسط افزونه‌ي YSlow به صورت زير خواهد بود: