代码改变世界

Web开发中的缓存技术之二:基于访问时间的简单缓存

2010-04-04 21:45  姜 萌@cnblogs  阅读(585)  评论(0编辑  收藏  举报

没有一劳永逸的缓存技术,每种缓存方式都适用于一种特定场合,本文通过ActionFilter为ASP.NET MVC应用提供一种最简单的基于访问时间的缓存方法。

使用场合:变动不是很频繁的动态页面,比如首页,目录页面之类。

效果描述:每次服务器返回数据给客户机都设置response头中的LastModified值以及浏览器缓存过期时间。下一次浏览器再次访问此url时会在request头中含有Is-Since-Modified信息,服务器将Is-Since-Modified中的日期与当前日期做比较,如果在允许时间差范围内就认为无需为客户浏览器更新数据,直接将HTTP状态置为304。

代码不多,就直接贴出来了。

namespace Sopaco.Lib.Web.Mvc.Performance.Cache
{
    /// <summary>
    /// 仅根据客户机上次访问的时间戳进行简单缓存处理
    /// </summary>
    public class LazyCacheFilter : ActionFilterAttribute
    {
        #region Properties
        public long Seconds = 60;
        public TimeSpan MaxAge = new TimeSpan(1, 0, 0, 0);
        #endregion

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var response = filterContext.HttpContext.Response;
            string sinceTag = request.Headers["If-Modified-Since"];
            if (sinceTag != null &&
                TimeSpan.FromTicks(DateTime.Now.Ticks - DateTime.Parse(sinceTag).Ticks).Seconds < Seconds)
            {
                response.StatusCode = 304;
                response.StatusDescription = "Not Modified";
            }
            else
                setClientCaching(filterContext.HttpContext, DateTime.Now);
        }

        #region private Helper Methods
        private void setClientCaching(HttpContextBase context, DateTime time)
        {
            var cache = context.Response.Cache;
            cache.SetETag(time.Ticks.ToString());

            cache.SetLastModified(time);
            cache.SetMaxAge(MaxAge);
            cache.SetSlidingExpiration(true);
            cache.SetCacheability(HttpCacheability.Public);
        }
        #endregion
    }
}

应用:

[HandleError]
    public class HomeController : Controller
    {
        [LazyCacheFilter(Seconds=120)]
        public ActionResult Index()
        {
            //ViewData["Message"] = DateTime.Now.ToString();
            ViewData["Message"] = "this is from asp.net mvc develop server";
            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }