Aleksei Chepovoi
Aleksei Chepovoi

Reputation: 3955

How to cache output of action method that returns image to the view in asp.net mvc?

I've read lots of posts about caching already, but none of them actually match my needs exactly. In my mvc 3 app I have an action method GetImage() that returns a File of image type. Then I use this method in a view to display image:

<img width="75" height="75" src="@Url.Action("GetImage", "Store", new {productId = item.ProductId})"/>

I want to cache images on a Server. So, what I've already tried:

1) to use OutputCacheAttribute:

    [HttpGet, OutputCache(Duration = 10, VaryByParam = "productId", Location = OutputCacheLocation.Server, NoStore = true)]
    public FileContentResult GetImage(int productId)
    {
        var p = _productRepository.GetProduct(productId);
        if (p != null)
        {
            if (System.IO.File.Exists(GetFullProductImagePath(productId)))
            {
                var image = Image.FromFile(GetFullProductImagePath(productId));
                return File(GetFileContents(image), "image/jpeg");
            }
        }
        var defaultPath = AppDomain.CurrentDomain.BaseDirectory +
                             ConfigurationManager.AppSettings["default-images-directory"];

        var defaultImage = Image.FromFile(Path.Combine(defaultPath, "DefaultProductImage.jpg"));
        return File(GetFileContents(defaultImage), "image/jpeg");
    }

Images are not cached (I get status: 200 OK)

2) to use the following Response.Cache methods in a GetImage() method:

    public FileContentResult GetImage(int productId)
    {
        Response.Cache.SetCacheability(HttpCacheability.Public);
        Response.Cache.SetMaxAge(new TimeSpan(0, 0, 0, 10));
        Response.Cache.SetExpires(DateTime.Now.Add(new TimeSpan(0, 0, 0, 10)));
        Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");        
        // other code is the same
    }

Images are not cached

3) Here I get: 304 Not Modified, but the GetImage() method returns nothing (empty image)

    public FileContentResult GetImage(int productId)
    {
        Response.StatusCode = 304;
        Response.StatusDescription = "Not Modified";
        Response.AddHeader("Content-Length", "0");     
        // other code is the same
    }

Question: How to cache the output of this action method on a server?

Upvotes: 11

Views: 6168

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038780

Try like this:

[HttpGet]
[OutputCache(
    Duration = 10, 
    VaryByParam = "productId", 
    Location = OutputCacheLocation.ServerAndClient)]
public ActionResult GetImage(string productId)
{
    ...
}

Things to notice: using OutputCacheLocation.ServerAndClient and gotten rid of NoStore = true.

Upvotes: 14

Related Questions