views:

3630

answers:

4

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.

+5  A: 

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.

Hope that helps!

Zachary Yates
A: 

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
Aren't HttpContext.Cache and the OutputCache different? I could be wrong, but your example is dealing with the HttpContext.Cache.
Zachary Yates
@Zach Yes, they have no real relation.
bzlm
+7  A: 

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.

Simon_Weaver
Yeah, what's up with this? Why does it send "Vary: *" if you set VaryByParam to "none"?
bzlm
i'm still confused about this!
Simon_Weaver
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
@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
Or, to remove Vary: *, use this.Response.Cache.SetOmitVaryStar(true);
Kevin Hakanson
+2  A: 

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
+1 for doing my head in!
Simon_Weaver