如何将缓存共享添加到ASP.NET MVC站点中的所有图像

时间:2014-10-10 12:33:47

标签: c# asp.net-mvc caching browser-cache httpmodule

我正在尝试提高大型ASP.NET MVC网站的性能,我目前正在寻找一种方法来添加缓存清除查询字符串到图像请求,以便我不必去通过所有视图和CSS并更改每个图像参考。

期望的结果

验证是否正在添加缓存破坏程序我在Firefox中使用Firebug扩展程序,我希望看到的是这样的(截图来自其他网站)

enter image description here

我尝试了什么

在我看来,最简单的答案是创建一个自定义的HttpModule,它拦截任何图像请求,然后将缓存清除查询字符串附加到请求URL。所以我写了下面的课程

public class CacheBusterImageHandler : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += this.BeginRequest;
    }

    public void Dispose()
    {            
    }

    public void BeginRequest(object sender, EventArgs e)
    {
        // This conditional check will need to be modified to capture other image types
        // but for testing purposes it is good enough
        if (HttpContext.Current.Request.Path.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
        {
            // The version number will be generated but again for testing purposes this
            // is good enough
            var pathWithCacheBuster = string.Format("{0}?v1.0.0.0", HttpContext.Current.Request.Path);

            HttpContext.Current.RewritePath(pathWithCacheBuster);
        }
    }
}

然后我按照这个

在web.config中注册了该模块
<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="CacheBusterImageHandler" type="MyAssembly.CacheBusterImageHandler" preCondition="managedHandler" />
    ...

然后我验证了模块通过使用断点处理请求,但是当我在Firebug中检查时,的图像请求已将缓存绑定器附加到URL。然后我决定阅读RewritePath方法的文档,发现它当然只是重定向请求但不会改变请求的URL。

问题

HttpModule中是否有办法将缓存占用符附加到查询字符串中?

如果没有,是否有其他方法可以实现相同的结果,而无需修改对图像的每个引用?

1 个答案:

答案 0 :(得分:1)

  

“在HttpModule中是否有办法将缓存接收器附加到   查询字符串?“

没有。在这个过程中,这已经很晚了。将URL放入页面时,必须更改URL,这是浏览器用来检查图像是否在缓存中的内容。

  

“如果没有,有没有其他方法可以在没有的情况下达到相同的结果   必须修改对图像的每个引用?“

这取决于您如何将图片网址放在网页中,但无法更改网址,以便将URL放入网页。

您可以创建一个计算要包含的版本号/字符串的方法,并将其添加到所有URL。这样,您只需进行一次更改,而不是每次更改图像。

如果要在每次部署页面时使缓存无效,或者图像文件的更新时间不足,则该方法可以使用程序集的版本号或编译时间。

基本上:

<img src="/images/logo.png<%= ImageVersion("/images/logo.png") %>" alt="Logo">

使用类似的东西:

public static string ImageVersion(string name) {
  FileInfo info = new FileInfo(HttpContect.Current.MapPath(name));
  int time = (int)((info.LastWriteTimeUtc - new DateTime(2000,1,1)).TotalMinutes);
  return "?v=" + time.ToString();
}