روی سایتی کار می کردم که بعد از آپلود سایت روی هاست متوجه شدم وقتی به یه آدرس سایت می رم به جای اینکه صفحه توی مرورگر نمایش داده بشه پنجره دانلود مرورگر نمایش داده میشه و می خواد محتویات کامل صفحه رو دانلود کنه. توی گوگل سرچ کردم تا ببینم مشکل از کجاست متوجه شدم بخاطر استفاده از Cache در صفحات ASP.NET هست.
مشکل خیلی ساده بود. شما صفحه ای دارید که در بالای اون نوشتید:
<%@ OutputCache Duration="25" VaryByParam="None" %>
این کار یه کار معمولیه که باعث میشه صفحه به مدت 25 ثانیه هم در حافظه نهان مرورگر کاربر (Client) و هم در حافظه نهان سرور(Server) و هم در سرورهای واسط بین سرور و مرورگر کاربر (Proxy Server) اصطلاحاً Cache شود و نیازی به بازیابی اطلاعات صفحه نیست. مشکل وقتی بوجود می آید که این صفحه زمانی که در سرورها کش می شود برای کدام مرورگر این کار انجام میشود. تصور کنید زمانی که قرار است این صفحه کش شود درخواست توسط مرورگر یک موبایل انجام شود. سرور اطلاعات صفحه را برای مرورگر یک موبایل کش می کند و تا 25 ثانیه بعد اگر مرورگری از نوع دیگر مثلاً PC درخواست همان صفحه را بکند سرور اطلاعات صفحه را بصورت کش شده به درخواست کننده ارسال می کند و از آنجائیکه مرورگر موبایل Content-Type درخواستی را بصورت text/vnd.wap.wml مشخص میکند و مرورگر دیگر هم به همین صورت اطلاعات را دریافت می کند بنابراین به دلیل ناشناخته بودن Content-Type برای مرورگر PC پنجره دانلود نمایش داده میشود و کل صفحه به صورت یک فایل دانلود می شود.
برای حل مشکل باید از صفت VaryByCustom از OutputCache استفاده کنیم. بدین صورت:
<%@ OutputCache Duration="25" VaryByParam="None" VaryByCustom="browser" %>
این کار باعث میشود که اطلاعات کش شده به تفکیک نوع مرورگر کش شود. همچنین browser برای دات نت شناخته شده است که اتوماتیک این کار انجام میشود. ولی این جمله از MSDN گفته شده و عملاً این کار انجام نمی شود. برای اطمینان از این کار باید در فایل Global.asax متدی رو override کنید. بدین صورت:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "browser")
{
return Request.Browser.Browser;
}
}
این کار باعث می شود که صفحات به تفکیک مرورگر و دقیقاً نوع مرورگر مثلاً IE، یا Firefox کش شود. حتی برای اطمینان کامل می توانید نسخه مرورگر کاربر یعنی Request.Browser.MajorVersion یا Request.Browser.MinorVersion را هم دخالت دهید. بدین صورت:
return Request.Browser.Browser +
Request.Browser.MajorVersion +
Request.Browser.MinorVersion;
همین!