OutputCache behavior in ASP.NET MVC 3

后端 未结 2 1097
梦谈多话
梦谈多话 2021-01-31 22:46

I was just testing Output Caching in the RC build of ASP.NET MVC 3.

Somehow, it is not honoring the VaryByParam property (or rather, I am not sure I understand what is g

2条回答
  •  轮回少年
    2021-01-31 23:07

    VaryByParam only works when the values of the url look like /user/view?slug=abc. The params must be a QueryString parameter and not part of the url like your above examples. The reason for this is most likely because Caching happens before any url mapping and that mapping isn't included in the cache.

    Update

    The following code will get you where you want to go. It doesn't take into account stuff like Authorized filters or anything but it will cache based on controller/action/ids but if you set ignore="slug" it will ignore that particular attribute

    public class ActionOutputCacheAttribute : ActionFilterAttribute {
        public ActionOutputCacheAttribute(int cacheDuration, string ignore) {
            this.cacheDuration = cacheDuration;
            this.ignore = ignore;
        }
    
        private int cacheDuration;
        private string cacheKey;
        private string ignore;
    
        public override void OnActionExecuting(ActionExecutingContext filterContext) {
            string url = filterContext.HttpContext.Request.Url.PathAndQuery;
            this.cacheKey = ComputeCacheKey(filterContext);
    
            if (filterContext.HttpContext.Cache[this.cacheKey] != null) {
                //Setting the result prevents the action itself to be executed
                filterContext.Result =
                (ActionResult)filterContext.HttpContext.Cache[this.cacheKey];
            }
    
            base.OnActionExecuting(filterContext);
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext) {
            //Add the ActionResult to cache 
            filterContext.HttpContext.Cache.Add(this.cacheKey, filterContext.Result,null, DateTime.Now.AddSeconds(cacheDuration),
              System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
    
            //Add a value in order to know the last time it was cached.
            filterContext.Controller.ViewData["CachedStamp"] = DateTime.Now;
    
            base.OnActionExecuted(filterContext);
        }
    
        private string ComputeCacheKey(ActionExecutingContext filterContext) {
            var keyBuilder = new StringBuilder();
            keyBuilder.Append(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
            keyBuilder.Append(filterContext.ActionDescriptor.ActionName);
    
            foreach (var pair in filterContext.RouteData.Values) {
                if (pair.Key != ignore) 
                    keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
            }
            return keyBuilder.ToString();
        }
    }
    

提交回复
热议问题