Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET HttpModule重写路径虚拟目录缓存未刷新_Asp.net_Caching_Url Rewriting_Iis 7.5 - Fatal编程技术网

ASP.NET HttpModule重写路径虚拟目录缓存未刷新

ASP.NET HttpModule重写路径虚拟目录缓存未刷新,asp.net,caching,url-rewriting,iis-7.5,Asp.net,Caching,Url Rewriting,Iis 7.5,我有一个ASP.NET IHttpModule实现,用于重写服务文件的路径。该模块仅处理一个事件,PostAuthenticateRequest,如下所示: void context_PostAuthenticateRequest(object sender, EventArgs e) { if (HttpContext.Current.Request.Path.ToLower().Contains("foobar")) { HttpContext.Current

我有一个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秒到几分钟)后返回当前版本。如果我用
    http://myserver/iismodulecachetest/virtdir/image.png
    ,问题似乎没有出现。但奇怪的是,在使用“foobar”URL出现问题后,直接URL也开始返回图像的过期副本

    相关细节:

  • 循环使用应用程序池可解决此问题
  • 等待一段时间可以解决问题
  • 反复重新保存文件似乎没有效果。我想知道“文件修改”事件是否丢失,但一旦卡住,我可以保存六次修改,Iis仍然不会返回新副本
  • 禁用web.config中的缓存没有任何区别<代码>
  • 这是一个虚拟目录这一事实似乎很重要,我无法复制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会显示每次都会触发
    上下文\u PostAuthenticateRequest
    事件处理程序,并且无论缓存是否被卡住,其行为都是相同的
  • Edit2-IIS日志:

    我在IIS中启用了“失败的请求跟踪”(有趣的是,如果配置适当,这如何适用于未失败的请求)。在步骤17之前,管道是相同的,其中返回过期版本的请求清楚地显示缓存命中

    第一个请求看起来很好,但缓存未命中:

    但一旦被卡住,它会重复显示缓存命中:

    可以理解的是,缓存命中后的事件与缓存未命中的情况大不相同。看起来IIS完全满足于认为其文件缓存是最新的,而实际上它绝对不是最新的!:(

    再往下一点,我们会看到第一个请求:

    然后是后续(故障)缓存命中请求:


    还请注意,目录显然受到监视,根据
    FileDirmoned=“true”

    您可以执行以下操作

    void context_PostAuthenticateRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.Path.ToLower().Contains("foobar"))
        {
            Random rnd = new Random();
            int randomNumber = rnd.Next(int.MinValue, int.MaxValue);
            HttpContext.Current.RewritePath("virtdir/image.png?"+randomNumber);
        }
    }
    

    使用方法
    RewritePath
    来处理虚拟目录中的静态资源时,我也遇到了同样的问题。 我没有使用此方法的解决方案,但最后我选择使用方法
    Server.TransferRequest
    ,这表明没有缓存问题

    HttpContext.Current.Server.TransferRequest(newUrl);
    

    请求传输将由
    IHttpModule
    再次处理,因此您需要小心不要产生循环。

    能否确认文件上的修改日期确实发生了更改?是的,刚刚测试过。Windows资源管理器清楚地显示了文件的新修改日期,但IIS仍返回旧版本。Http标头“上次修改"也将返回旧的修改日期。我将与Microsoft一起打开一个支持票证。这显然是一个bug,所以它应该是100%免费的。MS支持票证。-叹气-每次我提出其中一个,我都会有一头白发。我也不是开玩笑。我8年前第一次头发变白,是为了处理虚拟路径提供程序impleme中的ASP.NET内存泄漏Intation…在那场惨败中了解了整个ASP.NET团队。不过,他们很快就修补了。原则上,我认为这会破坏缓存,从而绕过这个问题,尽管在实践中,
    Random
    的实例需要作为一个单例来处理,以避免重复值。