从MVC3应用程序清除IIS缓存

时间:2012-01-26 16:38:32

标签: asp.net-mvc-3 caching iis-7

我需要清除服务器上的IIS缓存。具体原因详见下文;但原因并不重要。我完全确定这是我需要的解决方案;如下所述,我使用了消除过程来确定这确实是我面临的问题,以及我需要的解决方案。


我有一个MVC3应用程序的主题(skinnable架构)。把它想象成Wordpress;用户可以开发主题,下载并在其网站上激活它。主题完全控制最终的HTML输出。这是一种过度简化,因为我提供了一个API,其中包含了主题所使用的有用功能。

无论如何,用户可以更改网站的主题。主题目前存储在静态变量中。呈现视图页面时,主题的名称确定布局文件的位置(包含对CSS文件的引用等)和视图文件。主题是在DB中持续存在的设置。

例如,如果我有一个名为" Foo"的主题,那么在请求/ Admin页面时,我可能会使用/Themes/Foo/Admin.cshtml。如果我有另一个名为" Bar"没有该文件,然后对于/ Admin,它可能会请求/Themes/Bar/Generic.cshtml作为布局。

问题是更改主题意味着网站上的每个页面都已过时。这意味着在IIS7上缓存的任何网站都将显示旧主题;这是不正确的。我需要他们来展示新的主题。

无论如何,IIS7默认使用缓存。我基本上需要一种方法来在用户更改主题时清除缓存。目前,这种情况并没有发生,用户继续看到旧主题,直到缓存(某种程度上)到期为止。

使用输出缓存或任何其他形式的显式缓存;这是一个"香草"从缓存角度看ASP.NET MVC3应用程序(即我没有添加/配置任何缓存)。 IIS7有自己的默认缓存。我知道这一点,因为如果我在IIS7中为我的站点禁用输出缓存,我将在更改后始终看到正确的主题。

如何刷新缓存?其他SO问题指向使用Cache.blah,我尝试使用HttpContext.Current,但在测试期间(使用VS测试工具)为null - 因为ASP.NET管道未完全使用。

在集成测试中解释一下,我基本上是:

  • 转到localhost / Test /
  • 登录(将值提交到表单中)
  • 通过浏览到右侧页面并单击右侧链接来更改主题
  • 请求另一页
  • 查看主题是否已更改(基于布局/ css文件名)。

这完全由代码完成;我使用HtmlUnit的C#端口,并将我的应用程序部署到IIS中的/ Test,我基本上可以像最终用户一样浏览它。

目前,此测试大约有50%的时间通过。问题是IIS正在缓存结果,我无法在服务器端干净可靠地重置缓存。

同样,我不是在谈论清除会话或用户端缓存; IIS本身就是缓存我的应用程序的罪魁祸首。我也不想通过IIS设置完全禁用缓存,a)因为我不能强迫安装我的应用程序的人这样做,并且b)因为缓存很好。

那么如何强制刷新服务器上的缓存呢?

例如,我尝试以编程方式触摸web.config;这工作,但循环我的应用程序池,因此,杀死我的静态变量;每个请求都意味着从数据库重新加载所有静态变量,这会影响我的性能。

5 个答案:

答案 0 :(得分:2)

根据您的要求,我修改了这篇文章:

你可以使用输出缓存,你说所选主题存储在数据库中(比如网站的设置)好吧我会添加另一个列说GUID然后用它作为varybycustom值。

您的global.asax文件将能够运行代码:

void Page_Init() {

///code here to get the GUIDforthissitestheme

var outputCacheSettings = new OutputCacheParameters() {
    Duration = Int32.MaxValue, //think its maxvalue
    VaryByCustom = GUIDforthissitestheme
};
InitOutputCache(outputCacheSettings); 

}

至少在这里您将拥有输出缓存,但每次更改主题时,都会更改GUID,因此更改缓存,然后您的页面应该是新的。

我在列出产品的网站上做了类似的事情,当产品数据库更新时,密钥会被更改,但我无法找到我实施的网站,而且我在很多网站上工作

希望这会有所帮助

答案 1 :(得分:0)

设置'缓存规则'在'输出缓存'功能与文件缓存监控'设置为'使用文件更改通知'。然后触摸'文件主题更改会影响您可以执行的.net代码:

System.IO.File.SetLastWriteTimeUtc(fileName, DateTime.UtcNow);

答案 2 :(得分:0)

您描述的问题听起来很像客户端缓存问题。您是否使用Fiddler之类的HTTP代理进行了检查,以验证是否在客户端上缓存了这个问题?

如果您在模板更改后看到HTTP 304,则可能需要尝试配置IIS(或您的站点模板)以禁用客户端缓存。

答案 3 :(得分:0)

我不认为主题提到的方法是正确的。 如果我们使用STATIC变量,那么它将影响所有用户和所有页面。(当然不需要。)

我们可以想到两种方法,

  1. 在网址中使用主题名称,如果是RouteData,则将其设为prat。所以url“http:// myHost / BLUE / ..”将以BLUE主题返回,“http:// myHost / RED / ..”将以RED主题返回。如果用户将更改主题,则会更新网址。

  2. 上述方法的问题是下次用户浏览时,会加载默认主题。 因此,更好的方法是将主题保存为用户偏好的一部分。用户登录后,从DB中读取主题并设置RouteData值。

答案 4 :(得分:0)

只需触摸web.config即可。这是最简单,最可靠的方式。以编程方式刷新应用程序池是过度的。

如果您在查找web.config在测试环境中的位置时遇到问题(因为System.Web.HttpRequest.Current为空,而Server为类似),您始终可以使用app.config文件指向出去的位置。

同样,没有其他简单的方法可以做到这一点;如问题所述,甚至禁用输出缓存很难单独通过web.config完成。