取消ChildAction中的输出缓存

时间:2012-11-29 13:11:38

标签: c# asp.net-mvc

有谁知道是否可以取消代码中的输出缓存?我的意思是,如果我将输出缓存放在子操作上,如下所示我可以根据从子操作内部缓存的条件取消吗?

[ChildActionOnly]
[OutputCache(Duration = 36000, VaryByParam="tagslug")]
public virtual ActionResult MostViewed(string tagslug, int count)
{
    // Make an API call here. If not data returned do not cache the ChildAction as specified above
}

1 个答案:

答案 0 :(得分:1)

略读the framework source看起来唯一的逻辑就是不要缓存异常:

// Only cache output if this wasn't an error
if (!wasException) {
    ChildActionCacheInternal.Add(uniqueId, capturedText,
                                 DateTimeOffset.UtcNow.AddSeconds(Duration));
}

我无法找到解决此问题的绝妙方法:我认为您必须根据CodePlex的ASP.NET MVC源中的原始源自定义OutputCachingAttribute,然后添加对该行返回的额外检查,例如

if (!(wasException || capturedText.Contains("results:0"))) {

或类似的,或者找到一种方法从控制器向该代码传递一个标志。现有代码使用对象在会话上存储值;你可以复制一下,例如

  1. 定义与_childActionFilterFinishCallbackKey相同的新静态对象键,例如_noCacheResultKey
  2. 将一个公共静态方法添加到您可以调用的属性,例如

    public static void FlagNoCache(HttpContext httpContext) {
        httpContext.Items[_noCacheResultKey] = true;
    }
    
  3. 扩展ClearChildActionFilterFinishCallback以从.Items[]以及回调
  4. 中删除此内容
  5. 扩展上述测试以检查这一点。

    if (!(wasException
          || filterContext.HttpContext.Items.ContainsKey(_noCacheResultKey))) {
    
  6. 根据需要从您的控制器致电MyOutputCacheAttribute.FlagNoCache(Context);

  7. 也可以从您的代码中抛出异常,然后在另一个IExceptionFilter中捕获它,以便它不会超出OutputCacheAttribute但我不知道如何遗憾。