Custom outputcache provider with ASP.NET 4

Vote:
 

Hi,

Long story short, we're running ASP.NET 4 and EPiServer 6, and we'd like to write our own outputcache provider using the new System.Web.Caching.OutputCacheProvider in ASP.NET 4.

This works fine and dandy on a vanilla ASP.NET 4 website, but when EPiServer is added into the mix we get the following error:

When using a custom output cache provider like 'CustomOutputCacheProvider', only the following expiration policies and cache features are supported:  file dependencies, absolute expirations, static validation callbacks and static substitution callbacks.

Have anyone sucessfully implemented their own outputcache provider on an EPiServer CMS 6 installation running ASP.NET 4? Or does anyone perchance have an idea on how to do it?

#45266
Nov 03, 2010 16:36
Vote:
 

The reason this is failing is that the episerver output cache uses cache item dependencies (depend on another cache key) which doesn't seen ti be supported for custom output cache providers.

Below is a workaround that makes takes the exception away (but probably doesn't invalidate properly). The solution overrides a method in PageBase. I don't know whether this is viable in this situations, but perhaps it can help you along. I'd be interested to learn what you end up with.

        protected override void SetCachePolicy()
        {
            string cacheVaryByCustom = EPiServer.Configuration.Settings.Instance.HttpCacheVaryByCustom;
            int cacheVaryByCustomLength = cacheVaryByCustom.Length;

            Response.Cache.SetVaryByCustom(cacheVaryByCustom);

            string[] cacheVaryByParams = EPiServer.Configuration.Settings.Instance.HttpCacheVaryByParams;
            foreach (string varyBy in cacheVaryByParams)
            {
                Response.Cache.VaryByParams[varyBy] = true;
            }

            Response.Cache.SetValidUntilExpires(true);
            // Cannot use cache item dependency when using OutputCacheProvider
            // Response.AddCacheItemDependency(DataFactoryCache.VersionKey);
            Response.Cache.AddValidationCallback(new HttpCacheValidateHandler(ValidateOutputCache), null);
            DateTime cacheExpiration = DateTime.Now + EPiServer.Configuration.Settings.Instance.HttpCacheExpiration;
            DateTime stopPublish = CurrentPage != null ? CurrentPage.StopPublish : DateTime.MaxValue;
            Response.Cache.SetExpires(cacheExpiration < stopPublish ? cacheExpiration : stopPublish);
            Response.Cache.SetCacheability(EPiServer.Configuration.Settings.Instance.HttpCacheability);
        }

        private static void ValidateOutputCache(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            if (!UseOutputCache(context))
            {
                validationStatus = HttpValidationStatus.IgnoreThisRequest;
            }
        }

        private static bool UseOutputCache(HttpContext context)
        {
            return !PrincipalInfo.CurrentPrincipal.Identity.IsAuthenticated && EPiServer.Configuration.Settings.Instance.HttpCacheExpiration != TimeSpan.Zero && String.Compare(context.Request.HttpMethod, "GET", true) == 0;
        }    

 

#46507
Dec 15, 2010 11:30
Vote:
 

Thanks for the answer Christian.

I think we'll end up rolling our own cache provider, but it's still to be decided.

#46541
Dec 16, 2010 11:52
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.