【发布时间】:2013-01-22 12:00:44
【问题描述】:
我有一个 ASP.NET IHttpModule 实现,旨在重写服务文件的路径。该模块只处理一个事件,PostAuthenticateRequest,如下:
void context_PostAuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Path.ToLower().Contains("foobar"))
{
HttpContext.Current.RewritePath("virtdir/image.png");
}
}
路径“virtdir”是应用程序的虚拟目录子目录。应用程序本身运行在一个典型位置:C:\inetpub\wwwroot\IisModuleCacheTest\ 虚拟目录“virtdir”映射到 C:\TestVirtDir\
对http://myserver/iismodulecachetest/foobar 的请求将如预期的那样从虚拟目录返回 image.png。同样,对http://myserver/iismodulecachetest/virtdir/image.png 的请求将返回相同的图像文件。
然后我执行以下操作:
- 请求
http://myserver/iismodulecachetest/foobar - 直接修改C:\testvirtdir\image.png(在paint中更改颜色并重新保存)。
- 重复。
在间隔几秒钟重复 1 到 20 次后,返回的图像将是过期的副本。
一旦出现异常,服务器只会在经过未知时间(从 10 秒到几分钟)后返回当前版本。如果我将步骤 1 中的 URL 替换为 http://myserver/iismodulecachetest/virtdir/image.png,则似乎不会出现问题。但奇怪的是,在使用“foobar”网址出现问题后,直接网址也开始返回图像的过期副本。
相关细节:
- 应用程序池的回收解决了该问题。
- 稍等片刻即可解决问题。
- 反复重新保存文件似乎没有效果。我想知道“文件修改”事件是否丢失了,但一旦卡住,我可以保存六次修改并且 Iis 仍然不会返回新副本。
- 在 web.config 中禁用缓存没有任何区别。
<caching enabled="false" enableKernelCache="false" /> - 这是一个虚拟目录这一事实似乎很重要,我无法复制 image.png 作为应用程序本身内容的一部分的问题。
- 这不是客户端缓存,它肯定是服务器返回一个过时的版本。我已经通过检查请求标头、Ctrl+F5 刷新,甚至使用单独的浏览器验证了这一点。
- 我已经在两台机器上复制了这个问题。 Win7 Pro 6.1.7601 SP1 + IIS 7.5.7600.16385 和 Server 2008 R2 6.1.7601 SP1 + IIS 7.5.7600.16385。
编辑 - 更多详情:
- 在服务器级别禁用缓存和内核缓存没有区别。
- 向 URL 添加扩展名没有区别
http://myserver/iismodulecachetest/foobar.png。 - 将调试器附加到 IIS 显示每次都会触发
context_PostAuthenticateRequest事件处理程序,并且无论缓存是否卡住,其行为方式都相同。
Edit2 - IIS 日志:
我在 IIS 中启用了“失败的请求跟踪”(如果配置得当,这对于 non 失败的请求也很有趣。管道是相同的,直到第 17 步返回过期的请求版本清楚地显示缓存命中。
第一个请求看起来很好,但缓存未命中:
但是一旦卡住,就反复显示缓存命中:
可以理解,缓存命中后的事件与缓存未命中情况完全不同。看起来 IIS 完全满足于认为它的文件缓存是最新的,但它绝对不是! :(
我们看到第一个请求的堆栈再往下一点:
然后是后续(错误的)缓存命中请求:
另请注意,根据FileDirmoned="true",该目录显然受到监控。
【问题讨论】:
-
你能确认文件上的修改日期确实改变了吗?
-
是的,现在刚刚测试。 Windows 资源管理器清楚地显示文件的新修改日期,但 IIS 仍返回旧版本。 Http 标头“Last-Modified”也返回 old 修改日期。
-
我会向 Microsoft 开一张支持票。这显然是一个错误,所以它应该是 100% 免费的。
-
MS 支持票。 -sigh- 每次我举起其中的一个,我都会得到另一根白发。
-
不开玩笑,我也是。 8 年前,我第一次白发苍苍,处理虚拟路径提供程序实现中的 ASP.NET 内存泄漏......在那场惨败中认识了整个 ASP.NET 团队。不过,他们很快就修复了它。
标签: asp.net caching url-rewriting iis-7.5