Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use VaryByCustom with a Sitecore 7 Controller Rendering?

I have a Sitecore 7 Controller Rendering. I need to vary the OutputCache by a custom method.

The rendering is currently set to "Cachable", "VaryByData" and "VaryByParm" in Sitecore.

I've added an output cache attribute to my action, and set a custom vary string:

[OutputCache(VaryByCustom = "ThisIsATest", Duration = 60)]
public ActionResult Index()
{
    ...
}

My Global.asax inherits from Sitecore.Web.Application, and I've overridden GetVaryByCustomString as follows:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom == "ThisIsATest")
        return "some custom key";
    return base.GetVaryByCustomString(context, custom);
}

I'm never seeing the GetVaryByCustomString method fire, and the controller is behaving as though it didn't have an OutputCache attribute on it at all... It's as though it's actually just doing the default "Cachable", "VaryByData", "VaryByParm" behaviour from Sitecore.

Any clues?

like image 337
NeilD Avatar asked Jan 22 '14 15:01

NeilD


1 Answers

Ok, here's how I did it.

I added a checkbox field onto /sitecore/templates/System/Layout/Sections/Caching called "VaryByMyCustomThing".

Then I replaced the "GenerateCacheKey" pipeline in the Sitecore.Mvc.config with a custom implementation. I replaced this:

<processor type="Sitecore.Mvc.Pipelines.Response.RenderRendering.GenerateCacheKey, Sitecore.Mvc"/>

With this:

<processor type="My.Site.Pipelines.GenerateCustomCacheKey, My.Site"/>

My GenerateCustomCacheKey class looks like this:

using System.Net.Http;
using System.Web;
using Sitecore.Mvc.Extensions;
using Sitecore.Mvc.Pipelines.Response.RenderRendering;
using Sitecore.Mvc.Presentation;

namespace My.Site.Pipelines
{
    public class GenerateCustomCacheKey : GenerateCacheKey
    {
        protected override string GenerateKey(Rendering rendering, RenderRenderingArgs args)
        {
            var varyByCountryCode = rendering.RenderingItem.InnerItem["VaryByMyCustomThing"].ToBool();

            var key = base.GenerateKey(rendering, args);
            if (varyByCountryCode)
                key = key + GetCountryCodePart(rendering);
            return key;
        }    

        protected string GetCountryCodePart(Rendering rendering)
        {
            return "_#countryCode:" + (string)HttpContext.Current.Session["CountryCode"];
        }
    }
}
like image 57
NeilD Avatar answered Sep 30 '22 03:09

NeilD