I have a simple partial view that I'm rendering in my main view with:
@Html.Action("All", "Template")
On my controller I have this:
[OutputCache(CacheProfile = "Templates")]
public ActionResult All()
{
return Content("This stinks.");
}
And in my config this:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<clear/>
<add name="Templates" duration="3600" varyByParam="none"/>
</outputCacheProfiles>
</outputCacheSettings>
<outputCache enableOutputCache="false" enableFragmentCache="false" />
</caching>
This will fail at runtime with exception:
Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper
And inner exception:
Duration must be a positive number
Now obviously it's not picking up my web.config settings, because if I change it to:
[OutputCache(Duration = 3600)]
It will work, but also notice in my web.config I turned off enableOutputCache and enableFragmentCache, but it doesn't honor these settings.
Curiously, in a normal view these settings work fine, so what is it about partial views that is breaking this? Am I missing something? The Gu says this should work just fine... In short, is it supposed to honor caching settings in web.config and if not, why not?
So I took a minute and looked at the MVC 3 source. The first thing that came to me was this feature seemed a bit hacky. Mainly because they are reusing an attribute that works in one situation honoring all of the properties and config settings, and then in the child action scenario just ignoring all of those settings and only allowing VaryByParam and Duration.
How one would go about figuring out what is supported is beyond me. Because the exception they want to throw that says Unsupported Setting will never get thrown unless you supplied a duration and a VaryByParam value
Here is the main piece of code that smells:
I'm not sure why this isn't called out in documentation, but even if it was the api should make it clear, or at least throw the right exception.
In short, partial output caching works, BUTT not like you would want it too. I'll work on fixing the code and honoring some of the settings like enabled.
Update: I fixed the current implemenation to at least work for my situation with respecting the enabled flag and allowing cache profiles from the web.config. Detailed in my blog post.
Here's a simpler approach if :
All I did was created a new attribute 'DonutCache'.
Unfortunately you can only initialize an
[Attribute]
with a constant, so you need to initialize the attribute in its constructor. Note: This doesn't prevent you setting 'varyByParam' in the [DonutCache] declaration.Here I'm just initializing the attribute from my web.config by means of a static property:
Then of course you can use the XDT web transformation's you're already using to change this value