我做了研究,但没有找到任何答案。
我在母版页中使用Html.RenderAction(以显示具有特定于用户权限的链接的页眉)。动作用OutputCache装饰,返回部分控制并按预期进行缓存。
事件发生时(假设权限已更改),我想以编程方式使缓存的部分控件无效。
我正在尝试使用RemoveOutputCacheItem方法。它以路径作为参数。我正在尝试设置Html.RenderAction中使用的操作的路径。那不会使动作无效。
如何以编程方式使操作无效?
谢谢
最佳答案
子操作的缓存存储在OutputCacheAttribute.ChildActionCache属性中。问题在于,为子操作生成ID并将其存储在此对象中的API不是公开的(WHY Microsoft ??)。因此,如果您尝试遍历此集合中的对象,您会发现它还将包含子操作的缓存值,但是除非您对用于生成看起来像密钥的算法进行反向工程,否则您将无法识别它。像这样(用Reflector看到):
internal string GetChildActionUniqueId(ActionExecutingContext filterContext)
{
StringBuilder builder = new StringBuilder();
builder.Append("_MvcChildActionCache_");
builder.Append(filterContext.ActionDescriptor.UniqueId);
builder.Append(DescriptorUtil.CreateUniqueId(new object[] { this.VaryByCustom }));
if (!string.IsNullOrEmpty(this.VaryByCustom))
{
string varyByCustomString = filterContext.HttpContext.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, this.VaryByCustom);
builder.Append(varyByCustomString);
}
builder.Append(GetUniqueIdFromActionParameters(filterContext, SplitVaryByParam(this.VaryByParam)));
using (SHA256 sha = SHA256.Create())
{
return Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString())));
}
}
因此,您可以执行以下疯狂操作:
public ActionResult Invalidate()
{
OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault");
return View();
}
这显然会使所有缓存的子操作无效,这些操作可能不是您要找的,但恐怕是唯一的方法,除了对密钥生成进行逆向工程:-)。
@Microsoft,请,我求您使用ASP.NET MVC 4.0:
除了甜甜圈孔缓存之外,还引入了进行甜甜圈缓存的可能性
引入了使缓存的控制器操作的结果容易过期的可能性(MVCish比
Response.RemoveOutputCacheItem
更多)引入了使过期的子操作的结果轻松过期的可能性
如果您这样做1.那么显然会引入使缓存的甜甜圈部分过期的可能性。