With the [OutputCacheAttribute] in ASP.NET MVC 3, you can output cache with a good deal of flexibility. It's useful to leverage the 'VaryByHeader' property to bucket caching by host name. For example:
[OutputCache(Duration = 60, VaryByHeader = "host")]
public ActionResult Foo()
{
return this.View();
}
However, on child actions, you cannot apply the 'VaryByHeader'. The framework throws the following exception:
OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions.
My question is, why?
Is the reason why we cannot VaryByHeader in a child action because it would provide a conflicting variance, since the parent action might have specified a different VaryByHeader value?
If I want to cache child actions differently based upon hostname, what does this mean, and how would I go about it?
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.
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.
It allows varying the cached output by GET query string or form POST parameters. For instance, you can vary the user-control output to the cache by specifying the user-control name along with either a query string or a form POST parameter. For more information, see Caching Multiple Versions of User Control Output.
config file. By configuring output caching in the web configuration file, you can control it on one central location. You can create one cache profile and apply the profile to several controllers or controller actions. Also, you can modify the web configuration file without recompiling your application.
VaryByHeader
affects the actual HTTP Response headers; so you're probably correct that the MVC team blocked this to prevent conflicts with the parent action.
To cache based on hostname, couldn't you use VaryByCustom
? Something like (disclaimer: haven't tried this at all):
[OutputCache(Duration = 60, VaryByCustom = "host")]
public ActionResult Foo()
{
return View();
}
followed by (in your Global.asax.cs)
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "host")
{
return context.Request.Headers["host"];
}
// whatever you have already, or just String.Empty
return String.Empty;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With