I have been migrating a .NET 2.0 web forms application to use .NET 3.5 and a new infrastructure. There is a GridView inside an UpdatePanel, with an Actions column which contains icons to perform an action for that row. A problem that I am having in IE 6 is that images are not caching. This is particularly noticeable on the Actions column because there are 9 icons x 100 rows = 900 icons to load. Internet Explorer counts down these images from 900 until they are all loaded.
This problem does not appear to be limited to the images inside the GridView which is inside an UpdatePanel because I can see header images being reloaded each time there is a page refresh.
I have done my research:
- Anyone have ideas for solving the "n items remaining" problem on Internet Explorer? - this is a different problem.
- Dear IE6: Please Cache my Images. - I did think that this would solve all of the problems, but no. I have tried setting the image as a background image inside a div but no success. I also tried putting all icons inside a User Control and including this before the GridView is loaded.
- I have an old infrastructure (where this problem did not 开发者_运维知识库exist) to compare IIS configurations and they are exactly the same.
- Using Fiddler I can frustratingly see each image being requested. The Cache Header is
Cache-Control: private
. Just noticedDate: Tue, 29 Mar 2011 07:35:53 GMT
(which is an hour ago) in this Cache Header. Does that have anything to do with it? - This caching problem appears to be intermittent. I will load the page up for the first time and no images will be cached so ~1000 images will be independently loaded. I may refresh the page and images will be cached. If I delete all temporary files/offline content then the images will be loaded independently again.
- At first I thought this only occurred when deploying the application to the new infrastructure (requests being made cross-forest) but it does happen on my local machine too when all images are local.
- This is only a problem in IE 6!!!
Please let me know if I can provide other information.
UPDATE 1
Workarounds which have already been attempted with no success:
- The handler solution proposed by @Afshin Gh. UPDATE 2 The code in the answer actually works. A different version must have been attempted previously.
- The hidden images solution proposed by @Blue Steel.
UPDATE 2
Some of the other solutions may have worked here but I have gone with the code provided by @Afshin Gh.
Use this handler:
Public NotInheritable Class ImageHandler
Implements IHttpHandler
Private Const REQUEST_KEY As String = "pic"
Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
If Not String.IsNullOrEmpty(context.Request.QueryString(REQUEST_KEY)) Then
Dim fileName As String = context.Request.QueryString(REQUEST_KEY)
Try
Dim fileInfo As New IO.FileInfo(context.Server.MapPath(fileName))
If fileInfo.Exists Then
context.Response.Cache.SetCacheability(HttpCacheability.Public)
context.Response.Cache.SetExpires(Date.Now.AddYears(1))
Dim fileExt As String = fileInfo.Extension.Remove(0, 1).ToUpperInvariant
If fileExt = "JPG" Then
context.Response.ContentType = "image/jpeg"
Else
context.Response.ContentType = "image/" & fileExt
End If
context.Response.TransmitFile(fileInfo.FullName)
End If
Catch ex As Exception
End Try
End If
End Sub
End Class
Register it in your web.config:
<httpHandlers>
<add verb="*" path="image.axd" type="MyApp.ImageHandler, MyApp" validate="false"/>
</httpHandlers>
Use it like this:
<img src="image.axd?pic=/App_Themes/Modern/Logo.jpg" />
Does fiddler show cache control: private for other browsers as well? If so they won't be cached either. Are you using a custom control to serve up the images in the grid? If so you probably aren't handling the cache headers correctly (including 304 responses etc).
I suggest to set this cache parameters on header.
Response.Cache.AppendCacheExtension("post-check=900, pre-check=3600");
You can read more about here http://www.rdlt.com/cache-control-post-check-pre-check.html or google it.
Check it out and tell me if this solve your issue.
Have you tried adding the 9 images to the top of your page (outside the update panel) but set to hidden?
<asp:Image ID="Image1" ImageUrl = "images/img1.jpg" runat="server" style = "visibility:hidden" />
<asp:Image ID="Image2" ImageUrl = "images/img2.jpg" runat="server" style = "visibility:hidden" />
<asp:Image ID="Image3" ImageUrl = "images/img3.jpg" runat="server" style = "visibility:hidden" />
...
<asp:Image ID="Image9" ImageUrl = "images/img9.jpg" runat="server" style = "visibility:hidden" />
精彩评论