We are using MVC Donut Caching and have been all day trying to debug this problem which I still didn't manage to find a solution.
We have opted to start using the DonutOutputCache attribute over the OutputCache and through logging have noticed that certain partial view actions which have the DonutOutputCache attribute are not being cached as per the caching parameters.
We have a View (index) with the following nested partial views. The ones which have the donut cache attribute specified are listed in square brackets.
[DonutOutputCache(Duration = 3600)]
[DonutOutputCache(Duration = 3600)]
Through logging, we have discovered that the _HeaderMainMenu Partial View Action is actually being called multiple times in less than an hour time.
This is not happening:
Any insight towards what could be the reason?
Thanks for you help!
After downloading and checking the source code of the MVC Donut Caching project, we have finally found the reason towards why this was happening.
The DonutOutputCache attribute defined in this project makes use of an IKeyBuilder to generate the cache key used to store the output HTML in. The default DevTrends.MvcDonutCaching.KeyBuilder class which comes with the project generates a key which is made up of the following parts:
CacheSettings.Options
having the OutputCacheOptions.IgnoreQueryString
flag set on)CacheSettings.Options
having the OutputCacheOptions.IgnoreFormData
flag set on)VaryByParam
property set to:
none
, then all the querystring / form / route values are cleared*
, then it would just consider such parameters onlyVaryByCustom
parameter would end up calling the same GetVaryByCustomString
key generator within the System.Web.HttpApplication
.The above generated key was causing issues for us as a different key was being generated when we weren't aware of such parameters. For this reason, the methods were being called several times as since the website was on the product servers, users, search engines, bots and other requests with different querystring / form / route values where being passed and hence a new key was being generated.
Our solution was to create our own custom IKeyBuilder
which was passed on instead of the default IKeyBuilder
and solved this issue.