我尝试缓存对ASP.NET MVC3 RC1中的操作方法的调用。
缓存有效,但参数的变化似乎没有。我可以做些什么来使HotOffers的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>
部分(HotOffers.cshtml)
Hot offers
@Model.ProductID
答案 0 :(得分:1)
asp.net使用的缓存系统存在于MVC之外,因此仅适用于Urls,然后VaryByParam仅适用于QueryString参数。
我发布了一些代码OutputCache behavior in ASP.NET MVC 3,这可以让你根据参数进行缓存操作。那个特殊的例子我添加了一个“ignore”参数,它实际上会忽略其中一个路由字段,但你可以删除它,你应该没问题。
我想我可以在这里发布sans ignore
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/
的修改