Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Make browser cache images from action

I have an actionmethod that returns a File and has only one argument (an id).

e.g.

public ActionResult Icon(long id) {     return File(Server.MapPath("~/Content/Images/image" + id + ".png"), "image/png"); } 

I want the browser to automatically cache this image the first time I access it so the next time it doesn't have to download all the data.

I have tried using things like the OutputCacheAttribute and manually setting headers on the response. i.e:

[OutputCache(Duration = 360000)] 

or

Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetExpires(Cache.NoAbsoluteExpiration);  

But the image is still loaded every time I hit F5 on the browser (I'm trying it on Chrome and IE). (I know it is loaded every time because if I change the image it also changes in the browser).

I see that the HTTP response has some headers that apparently should work:

Cache-Control:public, max-age=360000

Content-Length:39317

Content-Type:image/png

Date:Tue, 31 Jan 2012 23:20:57 GMT

Expires:Sun, 05 Feb 2012 03:20:56 GMT

Last-Modified:Tue, 31 Jan 2012 23:20:56 GMT

But the request headers have this:

Pragma:no-cache

Any idea on how to do this?

Thanks a lot

like image 927
willvv Avatar asked Jan 31 '12 23:01

willvv


1 Answers

First thing to note is that when you hit F5 (refresh) in Chrome, Safari or IE the images will be requested again, even if they've been cached in the browser.

To tell the browser that it doesn't need to download the image again you'll need to return a 304 response with no content, as per below.

Response.StatusCode = 304; Response.StatusDescription = "Not Modified"; Response.AddHeader("Content-Length", "0"); 

You'll want to check the If-Modified-Since request header before returning the 304 response though. So you'll need to check the If-Modified-Since date against the modified date of your image resource (whether this be from the file or stored in the database, etc). If the file hasn't changed then return the 304, otherwise return with the image (resource).

Here are some good examples of implementing this functionality (these are for a HttpHandler but the same principles can be applied to the MVC action method)

  • Make your browser cache the output of a httphandler
  • HTTP Handler implementing dynamic resource caching
like image 55
brodie Avatar answered Sep 19 '22 16:09

brodie