0

I have a controller which returns SVG images.As I wanted to have good performances, I decide to use Caching.

From what I read on the web,once you set the last modified date with HttpContext.Response.Cache.SetLastModified(date) you can request it from the browser using HttpContext.Request.Headers.Get("If-Modified-Since"). Compare the two dates. If they are equal it means that the image has not been modified, therefore you can return HttpStatusCodeResult(304, "Not Modified").

But something weird is happening, here is my code:

[OutputCache(Duration = 60, Location = OutputCacheLocation.Any, VaryByParam = "id")]
   public ActionResult GetSVGResources(string id)
    {

        DateTime lastModifiedDate = Assembly.GetAssembly(typeof(Resources)).GetLinkerTime();

        string rawIfModifiedSince = HttpContext.Request.Headers.Get("If-Modified-Since");

        if (string.IsNullOrEmpty(rawIfModifiedSince))
        {
            // Set Last Modified time
            HttpContext.Response.Cache.SetLastModified(lastModifiedDate);
        }
       else
        {
            DateTime ifModifiedSince = DateTime.Parse(rawIfModifiedSince);

            if (DateTime.Compare(lastModifiedDate, ifModifiedSince) == 0)
            {
                // The requested file has not changed
                return new HttpStatusCodeResult(304, "Not Modified");
            }

        }

        if (!id.Equals("null"))
            return new FileContentResult(Resources.getsvg(id), "image/svg+xml");
        else
           return null;
    }

What is happening is the function HttpContext.Response.Cache.SetLastModified(lastModifiedDate); does not set the "If-Modified-Since" return from the browser, In fact the the function HttpContext.Request.Headers.Get("If-Modified-Since") retuns exactly the time when the image is returned from the previous call return new FileContentResult(Resources.getsvg(id), "image/svg+xml");.

So my question is,

1 - What does the function HttpContext.Response.Cache.SetLastModified(lastModifiedDate) set exactly ?

2 - How can I (the server) set the "If-Modified-Since" return by the browser ?

coldistric
  • 303
  • 1
  • 4
  • 14

1 Answers1

0

It seems like you're muddling a bunch of related but nonetheless completely different concepts here.

OutputCache is a memory-based cache on the server. Caching something there means that while it still exists in memory and is not yet stale, the server can forgo processing the action and just returned the already rendered response from earlier. The client is not involved at all.

HTTP cache is an interaction between the server and the client. The server sends a Last-Modified response header, indicating to the client when the resource was last updated. The client sends a If-Modified-Since request header, to indicate to the server that its not necessary to send the resource as part of the response if it hasn't been modified. All this does is save a bit on bandwidth. The request is still made and a response is still received, but the actual data of the resource (like your SVG) doesn't have to be transmitted down the pipe.

Then, there's basic browser-based caching that works in concert with HTTP cache, but can function without it just as well. The browser simply saves a copy of every resource it downloads. If it still has that copy, it doesn't bother making a request to the server to fetch it again. In this scenario, a request may not even be made. However, the browser may also send a request with that If-Modified-Since header to see if the file it has is still "fresh". Then, if it doesn't get the file again from the server, it just uses its saved copy.

Either way, it's all on the client. A client could be configured to never cache, in which case it will always request resources, whether or not they've been modified, or it may be configured to always use a cache and never even bother to check it the resource has been updated or not.

There's also things like proxies that complicate things further still, as the proxy acts as the client and may choose to cache or not cache at will, before the web browser or other client of the end-user even gets a say in the matter.

What all that boils down to is that you can't set If-Modified-Since on the server and you can't control whether or not the client sends it in the request. When it comes to forms of caching that involve a client, you're at the whims of the client.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Interesting, I didn't know if "outputcache" was a memory-based cache on the server side. But how do I check if I need to return the image or not ? Because the time return by "If-Modified-Since" is not the one where the image where last modified. – coldistric Feb 03 '16 at 19:49