ASP.NET中清除页面缓存

53
我想在我的博客中使用输出缓存,以保存一个特定文章的缓存版本约10分钟时间,这样做是可以的…
<%@OutputCache Duration="600" VaryByParam="*" %>

然而,如果有人发布了评论,我希望清除缓存,以便刷新页面并显示评论。

在ASP.Net C#中,我该如何做到这一点?

8个回答

49

我找到了我要寻找的答案:

HttpResponse.RemoveOutputCacheItem("/caching/CacheForever.aspx");

有人知道经典ASP是否有类似的东西可用吗? - Brettski
我认为在ASP中没有缓存可用,所以抱歉。 - GateKiller
这将清除该页面的所有参数的缓存。 - Sam Salim
2
我正在使用MVC 5.2.3,我应该在哪里编写这段代码? - Mohammad Dayyan
我正在使用 Web 用户控件来动态生成菜单,我正在使用 outputcache 并希望在注销时清除缓存。我使用了您的解决方案,并传递了我的用户控件路径,但对我没有起作用。 - Neha Thakur

41

如果您知道要清除缓存的页面,上述方法都是可以的。在我的情况下(ASP.NET MVC),我从各个地方引用了相同的数据。因此,在我执行[保存]操作时,我希望在整个网站上清除缓存。以下是适用于我情况的解决方法:http://aspalliance.com/668

这是在OnActionExecuting过滤器的上下文中完成的。也可以通过覆盖BaseController中的OnActionExecuting来轻松实现。

HttpContextBase httpContext = filterContext.HttpContext;
httpContext.Response.AddCacheItemDependency("Pages");

准备工作:

protected void Application_Start()
{
    HttpRuntime.Cache.Insert("Pages", DateTime.Now);
}

小调整: 我有一个帮助器,它会添加“闪存消息”(错误消息、成功消息-“此项已成功保存”等)。为了避免闪存消息在每个后续GET请求中都显示出来,我必须在写入闪存消息后使其无效。

清除缓存:

HttpRuntime.Cache.Insert("Pages", DateTime.Now);
希望这能有所帮助。

4
它仅适用于整个页面缓存,不适用于子操作。有任何建议吗? - Andrei M
3
安德,你解决了这个问题吗? - bobek
@and.maz 如果你已经想出如何在子操作中实现这一点,这里有一个悬赏任务 链接 - marapet
这对我没有用。无法清除缓存元素似乎是MVC中一个巨大的缺陷。 - Dave Lawrence
可能是因为您使用了@Html.Action()来呈现部分视图,所以您无法清除缓存。您需要使用OutputCacheAttribute.ChildActionCache = new MemoryCache("NewRandomStringNameToClearTheCache");来清除整个“子操作缓存”(适用于所有子操作 - 似乎没有更好的方法,除非使用库)。http://dotnet.dzone.com/articles/programmatically-clearing-0 - user2173353
@Kevin,你能解释一下如何在注销后清除网站的所有缓存页面吗? - Mohit Shah

6
使用Response.AddCacheItemDependency来清除所有输出缓存。
  public class Page : System.Web.UI.Page
  {
    protected override void OnLoad(EventArgs e)
    {
        try
        {
            string cacheKey = "cacheKey";
            object cache = HttpContext.Current.Cache[cacheKey];
            if (cache == null)
            {
              HttpContext.Current.Cache[cacheKey] = DateTime.UtcNow.ToString();
            }

            Response.AddCacheItemDependency(cacheKey);
        }
        catch (Exception ex)
        {
            throw new SystemException(ex.Message);
        }

        base.OnLoad(e);
    }     
 }



  // Clear All OutPutCache Method    

    public void ClearAllOutPutCache()
    {
        string cacheKey = "cacheKey";
        HttpContext.Cache.Remove(cacheKey);
    }

这也可以用于 ASP.NET MVC 的 OutputCachedPage。

完美,这正是我要找的。只有一件事需要更改。HttpContext.Current.Cache.Remove(cacheKey); - Sam Salim

3
在主页面加载事件中,请编写以下内容:
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();

并在退出按钮点击时:

Session.Abandon();
Session.Clear();

1
如果你将“*”更改为仅缓存应该变化的参数(PostID?),那么你可以像这样做:
//add dependency
string key = "post.aspx?id=" + PostID.ToString();
Cache[key] = new object();
Response.AddCacheItemDependency(key);

当有人添加评论时...

Cache.Remove(key);

我猜这个方法即使使用 VaryByParam * 也能生效,因为所有请求都会与同一个缓存依赖项相关联。


1

为什么不在帖子表上使用sqlcachedependency?

sqlcachedependency msdn

这样,您就不需要实现自定义缓存清除代码,只需在数据库中更改内容时刷新缓存即可。


1

嗯。您可以在OutputCache项上指定VaryByCustom属性。该值作为参数传递给您可以在global.asax中实现的GetVaryByCustomString方法。此方法返回的值用作缓存项的索引 - 如果例如返回页面上的评论数量,则每次添加评论时都会缓存一个新页面。

但是,这样做的警告是,它实际上并没有清除缓存。如果博客条目得到大量评论使用,使用此方法可能会导致缓存爆炸。

或者,您可以将页面的不可更改部分(导航、广告、实际博客条目)实现为用户控件,并在每个用户控件上实现部分页面缓存。


-1

HttpRuntime.Close() .. 我尝试了所有的方法,这是唯一一个对我有效的方法


7
我猜测这是在IIS上关闭ASP.NET应用程序进程。这似乎有点过度,可能会清除所有缓存并且会对大型网站造成重大的性能问题。 - GateKiller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接