public override void OnResultExecuting(ResultExecutingContext ctx) { if (!_enabled) { return; } if (ctx.Result is ContentResult) { return; } if (IgnoreCaching(ctx.Controller)) { SetDisablePageOutputCache(ctx, true); } string cacheKey = PopCacheKey(ctx); if (cacheKey == null) { return; } OutputCacheItem cachedOutput; SiteConfiguration.CacheProvider.TryGet(cacheKey, CacheRegions.RenderedOutput, out cachedOutput); if (cachedOutput == null) { StringWriter cachingWriter = new StringWriter((IFormatProvider)CultureInfo.InvariantCulture); TextWriter originalWriter = ctx.HttpContext.Response.Output; ViewModel model = ctx.Controller.ViewData.Model as ViewModel; ctx.HttpContext.Response.Output = cachingWriter; SetCallback(ctx, (viewModel, commitCache) => { ctx.HttpContext.Response.Output = originalWriter; string html = cachingWriter.ToString(); ctx.HttpContext.Response.Write(html); if (!commitCache) { return; } // since our model is cached we need to make sure we decorate the markup with XPM markup // as this is done outside the child action normally on a non-cached entity. // n.b. we should only do this if our text/html content if (ctx.HttpContext.Response.ContentType.Equals("text/html")) { if (model != null && WebRequestContext.IsPreview) { html = Markup.TransformXpmMarkupAttributes(html); } html = Markup.DecorateMarkup(new MvcHtmlString(html), model).ToString(); } OutputCacheItem cacheItem = new OutputCacheItem { Content = html, ContentType = ctx.HttpContext.Response.ContentType, ContentEncoding = ctx.HttpContext.Response.ContentEncoding }; // we finally have a fully rendered model's html that we can cache to our region SiteConfiguration.CacheProvider.Store(cacheKey, CacheRegions.RenderedOutput, cacheItem); if (viewModel != null) { Log.Trace($"ViewModel={viewModel.MvcData} added to DxaOutputCache."); } }); } }