16

I am using the standard outputcache tag in my MVC app which works great but I need to force it to be dumped at certain times. How do I achieve this? The page that gets cached is built from a very simple route {Controller}/{PageName} - so most pages are something like this: /Pages/About-Us

Here is the output cache tag that is at the top of my .aspx view page just to be clear:

<@ OutputCache Duration="100" VaryByParam="None" %>

So in another action on the same controller where content is updated I need to dump this cache, or even all of it - it's a very small app so not a big deal deal to dump all cached items.

Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155
Slee
  • 27,498
  • 52
  • 145
  • 243

4 Answers4

16

Be careful about using "None" vs. "".

  • If you send "" then the HttpHeader for Vary is not sent.
  • If you send "None" then the HttpHeader for Vary is sent.

I used Fiddler to verify this behavior.

This seems to have an impact on whether or not the browser goes back to the server to check for latest version (causing a 304). At least in Chrome it does. You want to use Varies="" if you know for sure you aren't going to want to update the file before it has expired.

I'd recommend using Varies="" as I did in this post. For my javascript file I dont want the browser going back and making another Http request until it has expired. 304 is unnecessary.

Community
  • 1
  • 1
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • Yeah, what's up with this? Why does it send "Vary: *" if you set VaryByParam to "none"? – bzlm Mar 01 '09 at 18:33
  • i'm still confused about this! – Simon_Weaver Mar 02 '09 at 10:50
  • 1
    confirmed, when you do `Varies="none"` you get the header `Vary: *` in the response. When you do `Varies=""` you get no such header. – Jeff Atwood Apr 27 '10 at 14:22
  • @jeff thanks for the confirmation. every time i end up back at my own post here i get confused and dubious about what i wrote. hope you'll post any more in depth findings back – Simon_Weaver Apr 27 '10 at 23:19
  • 8
    Or, to remove Vary: *, use this.Response.Cache.SetOmitVaryStar(true); – Kevin Hakanson Aug 13 '10 at 22:26
  • 1
    @KevinHakanson: Alternatively, set it for your whole app in your `web.config`: ``. – TheCloudlessSky Oct 30 '12 at 12:48
  • 3
    This is useful information, but it doesn't seem to answer the question asked, at least not without some context. @Slee, did you combine this answer with info from another one? If so, we should edit this answer to contain the necessary more-basic-info. How DO you dump the output cache? And how does "being careful about None vs """ relate to this question? – Seth Dec 16 '12 at 19:07
  • @Seth Was going to post the same thing... how is this an answer to the question? – Dave Lawrence Jun 25 '13 at 15:30
15

HttpResponse.RemoveOutputCacheItem() is probably the method you want to use. If you can figure out what name the actions are cached under, you can remove just the specific action (try setting a breakpoint or dumping all of the names of cached items to the screen)

Otherwise, I'd iterate through the entire output cache and just clear every item.

Zachary Yates
  • 12,966
  • 7
  • 55
  • 87
7

Not knowing the difference between "None" and "" for the VaryByParam, I was using this attribute:

[OutputCache(Location=OutputCacheLocation.ServerAndClient, Duration=int.MaxValue, VaryByParam="none")]

And this code to "fix" the Vary: * problem:

this.Response.Cache.SetOmitVaryStar(true);

Which I found referenced at ASP.NET caching tests find a bug with VaryByParam

The difference between a OutputCache directive set to "Client" and "ServerAndClient" is that "ServerAndClient" outputs the Vary field. This is impacting IE in that IE is sending requests regardless. The use of the vary:* header can disable all client caching (http://msdn2.microsoft.com/en-us/library/system.web.httpcachepolicy.setomitvarystar.aspx).

The only way to remove the vary:* header and thus allow client caching was through code:

Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155
1

it seems that output cache doesn't put anything in HttpContent.Cache because when I loop through it the collection is empty:

For Each elem As DictionaryEntry In HttpContext.Cache
  HttpContext.Cache.Remove(elem.Key)
Next

Here is my action attribute:

<OutputCache(Duration:=600, VaryByParam:="pagename")> _
Function Index(ByVal pagename As String) As ActionResult
Slee
  • 27,498
  • 52
  • 145
  • 243