Flush HTML cache on Sitecore Forms Submit

Created: 27 Aug 2021, last update: 30 Jan 2022

Flush HTML cache on Sitecore Forms Submit

When you use Sitecore Forms data in a Rendering like I explained in Sitecore Forms create a poll Then you should also think about caching to increase the scalability. The most convenient is of course to use Sitecore's out of the box html caching. Then it can be useful to trigger a flush cache after a form submit. This can be done by building a FlushCache Submit Action like this:

using Sitecore.Abstractions;
using Sitecore.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Sitecore.Diagnostics;
using Sitecore.Eventing;
using Sitecore.Eventing.Remote;
using Sitecore.ExperienceForms.Models;
using Sitecore.ExperienceForms.Processing;
using Sitecore.ExperienceForms.Processing.Actions;
using Sitecore.Publishing;
using System;
using Sitecore.Caching;

namespace RadioPollResult.SubmitActions
{
    public class FlushCache : SubmitActionBase
    {

        private IEventQueue defaultQueue;
        public FlushCache(ISubmitActionData submitActionData) : base(submitActionData)
        {
            this.defaultQueue = (IEventQueue)ServiceLocator.ServiceProvider.GetService();
        }
        protected override bool TryParse(string value, out string target)
        {
            target = string.Empty;
            return true;
        }

        protected override bool Execute(string data, FormSubmitContext formSubmitContext)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));

            //clear Html cache (only current site, if used on other sites, adjust this)
            CacheManager.GetHtmlCache(Sitecore.Context.Site).Clear();
            //raise a (fake) publish end remote event, to clear cache other servers..
            PublishOptions publishoption = new PublishOptions(Sitecore.Context.Database, Sitecore.Context.Database, PublishMode.SingleItem, Sitecore.Context.Language, DateTime.Now);
            var publisher = new Publisher(publishoption);
            defaultQueue.QueueEvent(new PublishEndRemoteEvent(publisher));
            return true;

        }
      
    }
}

This is raising a publish:end event and a publish:end:remote event for the possible other servers. This will flush the HTML cache of all websites that have this enabled. And trigger also everything else in the publish:end pipeline.

But why clear all cache if we only need to clear a few renderings of a single website. So use the Sitecore 10.1 Flush Partial Html Cache using the Clear On Content Update option. First enable the PartialHtmlCacheClear of your website, by default it is off.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <sites>
      <site name="website">
      	<patch:attribute name="enablePartialHtmlCacheClear">true</patch:attribute>
      </site>
    </sites>
  </sitecore>
</configuration>

And configure the rendering you want to flush.

You still need to Trigger this flush on a Form Sumit therefore you can trigger the item:saved and item:saved:remote this do still more than only flushing your rendering, but it is the easiest way, later in a next blog I explain how to do it nicer with a own event.

Specify the content Item the rendering use in the Form Save action. The nicest way is to do this with a Submit Action Editor, this is a lot of work for now we just use the “Redirect to page” editor Sitecore used for the “Redirect to Page” Submit Action it has the same functionality we need but it is textual not quite right. If you want, you can make a copy and modify it. See core database: /sitecore/client/Applications/FormsBuilder/Components/Layouts/Actions/ and for the related .js file see in the webroot \sitecore\shell\client\Applications\FormsBuilder\Layouts\Actions\

The Code for the Save action:

using Sitecore.Abstractions;
using Sitecore.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Sitecore.Diagnostics;
using Sitecore.Eventing;
using Sitecore.ExperienceForms.Models;
using Sitecore.ExperienceForms.Processing;
using Sitecore.ExperienceForms.Processing.Actions;
using System;
using Sitecore.Data.Items;
using Sitecore.Data;
using Sitecore;
using Sitecore.Data.Eventing.Remote;

namespace RadioPollResult.SubmitActions
{
    public class FlushPartialHtmlCache : SubmitActionBase
    {

        private IEventQueue defaultQueue;
        public FlushPartialHtmlCache(ISubmitActionData submitActionData) : base(submitActionData)
        {
            this.defaultQueue = (IEventQueue)ServiceLocator.ServiceProvider.GetService();
        }

        protected override bool Execute(FlushPartialHtmlCacheData data, FormSubmitContext formSubmitContext)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));

            if (data.ReferenceId == null || data.ReferenceId == Guid.Empty)
            {
                return false;
            }

            Sitecore.Data.Items.Item obj = Context.Database.GetItem(new ID(data.ReferenceId.Value));
            ItemChanges changes = new ItemChanges(obj);
            //optional do dummy change
            //Sitecore.Data.Fields.Field dummychange = obj.Fields[0];
            //changes.SetFieldValue(dummychange, dummychange.Value);

            Sitecore.Events.Event.RaiseEvent("item:saved", (object)obj, (object)changes);

            //raise a (fake) item saved remote event, to clear cache other servers.
            defaultQueue.QueueEvent(new SavedItemRemoteEvent(obj, changes), true, false);
            return true;
        }  
    }
}
using System;

namespace RadioPollResult.SubmitActions
{
    public class FlushPartialHtmlCacheData
    {
        public Guid? ReferenceId { get; set; }
    }
}

Note the model must match the values used in the Submit Action Editor,

See code on GitHub.