How to implement VaryByCustom caching?
Asked Answered
L

4

16

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?

Lauren answered 15/3, 2011 at 15:22 Comment(0)
N
6

You don't need to call SetVaryByCustom in MVC. You could use the OutputCache attribute. Checkout the following blog post.

Neoteny answered 15/3, 2011 at 15:27 Comment(8)
Hi Darin, thanks for the answer. I'm still a little confused though. I've updated the question to be more specific.Lauren
... actually, as I read further I can see that the example includes varybycustom="IsLoggedIn". This might be what I need! -- thanksLauren
that did the trick.. just to note though the attribute is case sensitive, so it's actually varyByCustom="host"Lauren
Blog post URL seems to have changed to visitmix.com/writings/…Trigonous
Both URLs (the one in the actual post, and the one in the comments) do not work.Repellent
The link is broken.Pentothal
Link to URL is broken. Info should've been included in the answer.Polyzoan
web.archive.org/web/20120618031112/http://visitmix.com/writings/…Countryfied
H
4

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.

Hypergolic answered 15/3, 2011 at 15:39 Comment(0)
H
3

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 the VaryByCustom property/attribute to "host", you would then write code inside GetVaryByCustomString 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.

Handbarrow answered 15/3, 2011 at 15:27 Comment(0)
W
0

Based on your edit, add VaryByCustom="host" to your FundScreener output cache profile.

Wrongly answered 15/3, 2011 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.