MVC Donut Caching not working as expected once deployed online
-
20-12-2019 - |
Frage
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.
- _LayoutMainBase.cshtml
- _Header (PartialView)
- _HeaderBottomStrip (PartialView)
- _HeaderMainMenu (ParialView)
[DonutOutputCache(Duration = 3600)]
- _HeaderMainMenu (ParialView)
- _HeaderBottomStrip (PartialView)
- RenderBody() (HomeController.Index)
[DonutOutputCache(Duration = 3600)]
- ...
- _Header (PartialView)
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:
- If we revert to the OutputCache attribute
- When testing locally on our work stations
Any insight towards what could be the reason?
Thanks for you help!
Lösung
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:
- Prefix
- Controller Name
- Action Name
- Querystring parameter values (depends on the
CacheSettings.Options
having theOutputCacheOptions.IgnoreQueryString
flag set on) - Form parameters (depends on the
CacheSettings.Options
having theOutputCacheOptions.IgnoreFormData
flag set on) - Route Values
- If you have
VaryByParam
property set to:none
, then all the querystring / form / route values are cleared- If you have it set to anything apart from
*
, then it would just consider such parameters only
VaryByCustom
parameter would end up calling the sameGetVaryByCustomString
key generator within theSystem.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.