2010-11-24 26 views
1

我嘗試緩存對ASP.NET MVC3 RC1中的操作方法的調用。緩存對Html.Action的調用

緩存工作,但通過參數的變化似乎沒有拿起。有什麼我可以做的,使3 HotOffers調用返回不同的結果取決於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> 

部分(HotOffers.cshtml)

Hot offers 
@Model.ProductID 
+1

修改這是由於在MVC 3 RC的功能不正確的設計。修補程序已被檢入到產品中,並應在下一版本中提供。 – Levi 2010-11-26 20:45:54

回答

1

asp.net使用的緩存系統在MVC之外,因此只適用於Url,然後VaryByParam只適用於QueryString參數。

我發佈了一些代碼OutputCache behavior in ASP.NET MVC 3,這應該讓你根據參數進行緩存操作。這個特殊的例子我添加了一個「忽略」參數,它實際上會忽略一個路由字段,但是你可以刪除它,你應該沒問題。

我想我可以將它張貼在這裏SANS忽略

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/