I'm trying to implement functionality to cache certain pages depending on the host. This is because I can have multiple versions of a page which have the same parameters, and where the only difference in terms of a request is the host that is being requested.
So, for example these two URLs will request the same page, but they are styled differently:
http://www.a.com/something/specific
and
http://www.b.com/something/specific
I'm going through the example outlined here:
http://msdn.microsoft.com/en-us/library/5ecf4420%28v=VS.90%29.aspx
but it's not making sense to me.
I've added this to my global.asax:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "host")
{
return "host=" + context.Request.Url.Host;
}
return base.GetVaryByCustomString(context, arg);
}
and the example states "To set the custom string programmatically, call the SetVaryByCustom method and pass it the custom string to use", with code similar to the following:
Response.Cache.SetVaryByCustom("host");
The problem is I'm not sure what to do with this. I've added the previous line to MvcApplication_EndRequest
because it seems like it makes sense, but I don't think this is right because when I set breakpoints in GetVaryByCustomString
they never get hit.
Can somebody please tell me what I'm missing here? Or if I need to do this differently?
Edit: RE Darin's answer below, I'm already decorating my actions with:
[CustomOutputCache(CacheProfile = "FundScreener")] // or similar depending on the action
where CustomOutputCacheAttribute
is defined as:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomOutputCacheAttribute: OutputCacheAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
AddLabelFilesDependency(filterContext);
base.OnResultExecuted(filterContext);
}
private static void AddLabelFilesDependency(ControllerContext filterContext)
{
IConfigurationManager configurationManager = ObjectFactory.TryGetInstance<IConfigurationManager>();
if (configurationManager == null
|| filterContext == null
|| filterContext.RequestContext == null
|| filterContext.RequestContext.HttpContext == null
|| filterContext.RequestContext.HttpContext.Response == null
)
{
return;
}
string[] files = Directory.GetFiles(configurationManager.LabelsDirectoryPath, "*.xml");
foreach(var file in files)
{
filterContext.RequestContext.HttpContext.Response.AddFileDependency(file);
}
}
}
where the profile is defined as:
<add name="FundScreener"
location="Server"
enabled="true"
varyByParam="*"
duration="1200"
sqlDependency="mmftms:offline.ScreenerData"/>
Do I need to change this?
GetVaryByCustomString(...)
is called by the caching layer per request and you have an opportunity to inspect the request and the passed-in argument to decide how to "categorize" this request. So if you set theVaryByCustom
property/attribute to "host", you would then write code insideGetVaryByCustomString
function which returns the host (as in your example, above). If the caching layer finds that it has already cached the argument "host" with the value you've returned then it will return the cached response, otherwise it executes the request and adds it to the cache.You don't need to call
SetVaryByCustom
in MVC. You could use theOutputCache
attribute. Checkout the following blog post.If you want to have different cache for different hosts, you can use:
VaryByHeader="host"
Because, that would make it use the value of header "host" in the request to vary the cache. You can add this in the OutputCache directive on your controllers/actions, or you can specify it globally in your web.config probably.
a host header will always be present if you use host-bindings, which seems to be the case for you.
Based on your edit, add
VaryByCustom="host"
to your FundScreener output cache profile.