Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 OutputCache not working on Server and Client as expected

I'm having trouble using the OutputCache attribute in Microsoft's MVC3 framework.

Please imagine the following controller action, which can be used as part of an AJAX call to get a list of products based on a particular manufacturerId:

public JsonResult GetProducts(long manufacturerId)
{
    return Json(this.CreateProductList(manufacturerId), JsonRequestBehavior.AllowGet);
}

I want this result to be cached on the server to avoid making excessive database queries. I can achieve this by configuring the attribute thus:

[OutputCache(Duration = 3600, Location = OutputCacheLocation.Server, VaryByParam = "manufacturerId")]

This works as I expected - the browser makes an intitial request which causes the server to create and cache the result, subsequent requests from the same or different browser get the cached version.

But... I also want the browser to cache these results locally; if I filter first on manufacturer X, then Y then go back to X, I don't want it to make another request for X's products - I want it to just use its cached version.

I can make this happen, by changing the OutputCache to this:

[OutputCache(Duration = 3600, Location = OutputCacheLocation.Client)]

Here's the question: how do I combine these so that I can have both sets of behaviour? I tried setting the Location to ServerAndClient but this just made it behave the same as when Location was Server.

I'm sure that the problem has something to do with the "Vary: *" response header I get with ServerAndClient but I don't know how to get rid of it.

I welcome comments about the rationality of my intentions - the fact that I'm not getting the results I expect makes me think I might have some fundamental misunderstanding somewhere...

Many thanks.

PS: This is on a local dev environment, IIS Express from VS2010.

like image 299
Adam Brown Avatar asked Aug 21 '12 09:08

Adam Brown


1 Answers

You can use OutputCacheLocation.Any which specifies

The output cache can be located on the browser client (where the request originated), on a proxy server (or any other server) participating in the request, or on the server where the request was processed. This value corresponds to the HttpCacheability.Public enumeration value.

You may want to also set Cache-control public to in the HTTP header for these requests.

Edit

It seems, depending on your .Net version of the web server you may need to include Response.Cache.SetOmitVaryStar(true); within your controller action to remove the Vary * headers as you suggest.

Details of the reason why in .Net 4 breaking changes release notes.

like image 128
AlexC Avatar answered Nov 15 '22 09:11

AlexC