locked
Caching HttpHandler output in the browser? RRS feed

  • Question

  • User1786436407 posted

    I have an HTTPHandler mapped to a custom file extension (*.tvgif) that I have set up in IIS.

    This handler serves images.

    I have a problem though in that the browser doesn't seem to cache the response in  the same way as it would a link to a gif on a server.

     Both IE and Firefox don't send the "If-Modified-Since" header.

    I have tried setting the cacheability to public and a week expiry but that doesn't seem to work either and the browser still makes a request rather than getting it from the cache.

    Do I need to add some additional  headers (perhaps the ETag? to get the response cached in the browser)

    I am using the code below (heavily "borrowed" from the FileResolver handler on code project)

        public class TreeViewImageMapper : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                HttpRequest Request = context.Request;
                HttpResponse Response = context.Response;
                NameValueCollection treeViewImageMappings = Global.TreeViewImageMappings;
    
                string filePath = context.Server.MapPath(treeViewImageMappings[Request.ServerVariables["Script_Name"].Substring(Request.ServerVariables["Script_Name"].LastIndexOf("/") + 1)]);
    
                if (!File.Exists(filePath))
                {
                    Response.StatusCode = 404;
                    Response.StatusDescription = "Not Found";
                    Response.End();
                    return;
                }
    
    
    
                DateTime lastModifiedTime = File.GetLastWriteTime(filePath);
    
                if (Request.Headers["If-Modified-Since"] != null)
                {
                    try
                    {
                        DateTime date = DateTime.Parse(Request.Headers["If-Modified-Since"]);
    
    
                        if (lastModifiedTime <= date)
                        {
                            // Don't do anything, nothing has changed since last request
                            //
                            Response.StatusCode = 304;
                            Response.StatusDescription = "Not Modified";
                            Response.End();
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        ErrorLogger.ReportError(ex);
                    }
                }
                else
                {
                    // In the event that the browser doesn't automatically have this header, add it
                    //
                    Response.AddHeader("If-Modified-Since", lastModifiedTime.ToString());
                }
    
    
                Response.Cache.SetCacheability(HttpCacheability.Public);
                Response.Cache.SetExpires(DateTime.Now.AddDays(7));
    
                //If we're still here then transmit the file
                Response.ContentType = "image/gif";
                Response.TransmitFile(filePath);
                Response.End();
                return;
            }
    
    
            public bool IsReusable
            {
                // To enable pooling, return true here.
                // This keeps the handler in memory.
                get { return true; }
            }
        }
    
     If-Modified-Since
    Sunday, May 6, 2007 9:34 AM

Answers

  • User1786436407 posted

    Got there in the end...

    Just needed to append the Etag header and delete the following lines

    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetExpires(DateTime.Now.AddDays(7));

    As when they were there they seemed to stop the Etag header being sent.

    I'm still not sure why those lines didn't make the browser cache it properly though?

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, May 6, 2007 10:35 AM