代码之家  ›  专栏  ›  技术社区  ›  Mathias F

缓存对html.action的调用

  •  1
  • Mathias F  · 技术社区  · 14 年前

    我尝试在ASP.NET MVC3 RC1中缓存对操作方法的调用。

    缓存工作正常,但参数的变化似乎没有恢复。有什么我可以做的,使3个电话热卖返回不同的结果取决于productid?

    现在的输出是

    热门产品4

    热门产品4

    热门产品4

    我希望输出

    热门产品4

    热门产品6

    热门产品8

    行动

    [OutputCache(Duration = 100, VaryByParam = "productId")]
    public PartialViewResult HotOffers(int productId)
    {
        ProductModel model = new ProductModel { ProductID = productId };
        model.Name = "Meatball";
    
        return PartialView(model);
    }
    

    (index.cshtml)

    @{
        View.Title = "Home Page";
    }
    <p>
    <div>
        @Html.Action("HotOffers", new { productid=4})
    </div>
    <div>
     @Html.Action("HotOffers", new { productid=6})
    </div>
     <div>
     @Html.Action("HotOffers", new { productid = 8 })
    </div>
    </p>
    

    部分 (hotpoffers.cshtml)

    Hot offers
    @Model.ProductID
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Community Nick Dandoulakis    7 年前

    ASP.NET使用的缓存系统存在于MVC之外,因此仅适用于URL,VaryByParam仅适用于QueryString参数。

    我贴了一些密码 OutputCache behavior in ASP.NET MVC 3 这将使您能够使用基于参数的缓存操作。这个特定的例子我添加了一个“忽略”参数,它实际上会忽略一个路由字段,但是您只需删除它,就可以了。

    我想我可以把它贴在这里而不忽略

    public class ActionOutputCacheAttribute : ActionFilterAttribute {
        public ActionOutputCacheAttribute(int cacheDuration) {
            this.cacheDuration = cacheDuration;
        }
    
        private int cacheDuration;
        private string cacheKey;
    
        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.Value != null)
                    keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
            }
            return keyBuilder.ToString();
        }
    }
    

    上面的代码是对 http://blog.stevensanderson.com/2008/10/15/partial-output-caching-in-aspnet-mvc/