Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is output caching not working for my ASP.NET MVC 4 app?

I am having an issue where output caching doesn't appear to be working for my ASP.NET MVC 4 (EPiServer 7) website.

I have the following output cache profile in my web.config:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="PageOutput" enabled="true" duration="300" varyByParam="*" location="ServerAndClient" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>

And here is my output caching configuration for static resources:

<caching>
  <profiles>
    <add extension=".gif" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="0.00:01:00" location="Any" />
    <add extension=".png" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="0.00:01:00" location="Any" />
    <add extension=".js" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="0.00:01:00" location="Any" />
    <add extension=".css" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="00:01:00" location="Any" />
    <add extension=".jpg" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="0.00:01:00" location="Any" />
    <add extension=".jpeg" policy="DontCache" kernelCachePolicy="CacheUntilChange" duration="00:01:00" location="Any" />
  </profiles>
</caching>

And my controller is decorated with an output cache attribute like so:

[OutputCache(CacheProfile = "PageOutput")]
public class HomePageController : BasePageController<HomePage>
{ ...}

I'm watching the following counters in perfmon but not seeing them increment as expected when I visit the home page:

  • \ASP.NET Apps v4.0.30319(__Total__)\Output Cache Entries
  • \ASP.NET Apps v4.0.30319(__Total__)\Output Cache Hits

I've also been testing using tinyget like so:

tinyget -srv:mywebsite -uri:/ -threads:1 -loop:20

Any advice would be greatly appreciated!

like image 741
JamesF Avatar asked Nov 17 '13 06:11

JamesF


People also ask

How output cache works in MVC?

The output cache enables you to cache the content returned by a controller action. That way, the same content does not need to be generated each and every time the same controller action is invoked. Imagine, for example, that your ASP.NET MVC application displays a list of database records in a view named Index.

What is the correct way to apply caching in MVC?

In ASP.NET MVC, there is an OutputCache filter attribute that you can apply and this is the same concept as output caching in web forms. The output cache enables you to cache the content returned by a controller action. Output caching basically allows you to store the output of a particular controller in the memory.

Where is output cache stored in MVC?

There is a property of the OutputCache attribute 'Location' with following possible values: Any (Default): Content is cached in three locations: the web server, any proxy servers, and the web browser. Client: Content is cached on the web browser. Server: Content is cached on the web server.

Where is output cache stored?

The output cache is located on the Web server where the request was processed. This value corresponds to the Server enumeration value. The output cache can be stored only at the origin server or at the requesting client. Proxy servers are not allowed to cache the response.


1 Answers

So, it turns out that OutputCaching was working, it was just that my method of testing it was flawed. The result of an action will only be cached if the response doesn't include a cookie. Of course the first response always includes a cookie if you have ASP.NET Session enabled which we do. Therefore the first response headers look like this:

HTTP/1.1 200 OK
Cache-Control: private, max-age=600
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Tue, 26 Nov 2013 03:48:44 GMT
Last-Modified: Tue, 26 Nov 2013 03:38:44 GMT
Vary: *
Set-Cookie: ASP.NET_SessionId=kbnhk4lphdlcpozcumpxilcd; path=/; HttpOnly
X-UA-Compatible: IE=Edge
Date: Tue, 26 Nov 2013 03:38:44 GMT
Content-Length: 9558

Assuming your browser or test tool can accept cookies and include those in the subsequent requests, the next request to the same page would result in HTTP response headers like so:

HTTP/1.1 200 OK
Cache-Control: private, max-age=598
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Tue, 26 Nov 2013 03:48:45 GMT
Last-Modified: Tue, 26 Nov 2013 03:38:45 GMT
Vary: *
X-UA-Compatible: IE=Edge
Date: Tue, 26 Nov 2013 03:38:45 GMT
Content-Length: 9558

As there is no client specific information in the response the output can now be cached as expected.

So, lesson is when testing output caching use a testing tool that can accept and return cookies in subsequent requests.

We ended up using Jmeter rather than tinyget and everything now works as expected.

like image 51
JamesF Avatar answered Sep 22 '22 22:09

JamesF