3

I have an ActionResult that returns a file result:

[OutputCache(VaryByParam = "document_id;size", Duration = 3 * 60 * 60, Location = OutputCacheLocation.Server)]
public ActionResult GetDocumentThumbnail(Guid document_id, int size)
{
    byte[] thumbnail = null;
    switch (size)
    {
        case 100:
            thumbnail =
                (from a in _unitOfWork.Documents
                    where a.Id == document_id
                    select a.Thumbnails.Thumbnail_100).First();
            break;

        case 25:
            thumbnail =
                (from a in _unitOfWork.Documents
                    where a.Id == document_id
                    select a.Thumbnails.Thumbnail_25).First();
            break;
    }
    return File(thumbnail, "image/png");
}

The Action gets cached properly, so after the first load, all the other requests doesn't goes into the Action body anymore.

The problem starts when i try to remove the cache for a specific document:

I have this function which i call but does nothing (the document thumbnail is still cached when i request it again)

private void RemoveDocumentThumbnailCache(Guid document_Id)
{
    HttpResponse.RemoveOutputCacheItem("/DocumentThumbnail/" + document_Id + "/");
}

I also tried this solution but with no result: I've added a custom route so the path doesn't contains query string parameters. Not working

routes.MapRoute(
    name: "DocumentThumbnail",
    url: "DocumentThumbnail/{document_id}/{size}",
    defaults: new { controller = "Home", action = "GetDocumentThumbnail" }
);

What i am doing wrong?

Community
  • 1
  • 1
Catalin
  • 10,580
  • 15
  • 68
  • 134
  • this might help http://antix.co.uk/Blog/IfModifiedAttribute – Zaki Jan 31 '14 at 09:44
  • have a look at http://ehsanghanbari.com/Post/21/different-kinds-of-caching-in-aspnet-mvc4, hope it helps – Ehsan Jan 31 '14 at 09:54
  • @Ehsan: `DonutCaching` [doesn't work](http://mvcdonutcaching.codeplex.com/workitem/2463) with `FileResult` actions – Catalin Jan 31 '14 at 09:57
  • @Zaki: I was hoping i can use `Asp.net OutputCache` attribute without having to create / use something else. It was supposed to work?!! – Catalin Jan 31 '14 at 09:58
  • DonutCaching is for special cases, you can use OutputCache for regular usages – Ehsan Jan 31 '14 at 10:03
  • @Ehsan: i am trying to use OutputCache but `RemoveOutputCacheItem` is not working – Catalin Jan 31 '14 at 10:05
  • you can use the RemoveOutputCacheItem of HttpResponse like this http://stackoverflow.com/questions/12612545/how-to-remove-output-cache-for-child-action-mvc3 – Ehsan Jan 31 '14 at 10:30

1 Answers1

1

RemoveOutputCacheItem must be the full relative URL. You are only passing in /DocumentThumbnail/{document_Id} when it should be /DocumentThumbnail/{document_Id}/{size}

private void RemoveDocumentThumbnailCache(Guid document_Id)
{
    foreach(var size in new[] { 100, 25 }) {
        var url = Url.Action("GetDocumentThumbnail", new { document_id = document_id, size = size });
        HttpResponse.RemoveOutputCacheItem(url);
    }
}
LostInComputer
  • 14,252
  • 4
  • 37
  • 47
  • 2
    This works! But is not very flexible, since i need to know all the values of other parameters in order to delete the entry. Is there any way of removing a cached item with by specifying only the start key? I've tried `/DocumentThumbnail/documentIdValue/*` but doesn't work – Catalin Jan 31 '14 at 10:36
  • Looked into it and doesn't seem to be possible. As with most caches, you can only access a cache entry via a key (exact URL path in this case). I can think of three alternatives: 1) Use VaryByCustom so that you can control if you will the existing cache or create a new one. Problem is you're not clearing the old cache entry. 2) Create a custom OutputCacheProvider. 3) change your URL so that `size` is in the query string instead of the URL path `/DocumentThumbnail/{document_Id}?size={size}`. – LostInComputer Jan 31 '14 at 15:27