Take the community feedback survey now.

SaveAction.Patch triggering Saving content event

Vote:
 

Hi all,

We have a website where on Instance_PublishedPage event we check whether a block has custom ID or not. If not, then contentId is copied to customID, and a clone is created and we call ContentRepository.Save(clonedPage,SaveAction.Patch, AccessLevel.NoAccess). But this is triggering SavingContent event -> SavedContent, -> Instance_PublishingPage event -> Instance_PublishedPage event thus going into a loop and causing 524 error.

Is there a way to not trigger SavingContent on SaveAction.Patch?

We are on Episerver.CMS 12.32.5

#340490
Sep 22, 2025 14:54
Vote:
 

Hi!

I may have misunderstood exactly what you’re trying to achieve, but from what you describe the recursion is happening because any call to ContentRepository.Save (even with SaveAction.Patch) will always fire the saving/saved events. If that call happens during PublishedContent, you can easily end up in a loop.

One way I’ve handled a similar case is to hook into the PublishingContent event instead. That lets you modify the content right before it’s persisted, without needing to call Save() yourself. For example:

[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class OptimizelyInfiniteLoopFix : IInitializableModule
{
    private IContentEvents? _contentEvents;

    public void Initialize(InitializationEngine context)
    {
        _contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();

        // Use PublishingContent instead of PublishedContent to avoid infinite loops
        _contentEvents.PublishingContent += OnPublishingContent;
    }

    private void OnPublishingContent(object? sender, ContentEventArgs e)
    {
        if (e.Content is SitePageData sitePageData && string.IsNullOrEmpty(sitePageData.CustomId))
        {
            // Modify content directly - no Save() call needed
            sitePageData.CustomId = e.Content.ContentLink.ID.ToString();
        }
    }

    public void Uninitialize(InitializationEngine context)
    {
        if (_contentEvents != null)
        {
            _contentEvents.PublishingContent -= OnPublishingContent;
        }
    }
}

At this stage of the pipeline, ContentLink.ID is always available, and the publishing process will persist the change for you. No extra save is required, so you avoid the loop.

Not sure if this lines up perfectly with your use case, but maybe it gives you another angle to try.

#340494
Edited, Sep 22, 2025 20:31
Vote:
 

Hi kristoffer, Thanks for the answer, it is helpful. One thing I am noticing is when I am calling ContentRepository.Save (with SaveAction.Patch) in the Instance_PublishingPage event, it is not firing the saving/saved events. Is there a difference in how this works based on whether we are in the publishing pipeline or not?

#340507
Sep 24, 2025 6:31
Vote:
 

Hi Priyanka,

At the publishing event, use this 

private void ContentEvents_PublishingContent(object sender, ContentEventArgs e)
{
    if (e.Content is SitePageData sitePageData)
    {
       SitePageData clone = (SitePageData)sitePageData.CreateWritableClone();
          clone.CustomId = e.Content.ContentLink.ID.ToString();
          contentRepo.Save(clone, SaveAction.Save,AccessLevel.NoAccess);
       
    }

}
#340517
Sep 24, 2025 13:30
Vote:
 

Hi,

As I mentioned in my previous post, there’s no need to create a writable clone and call ContentRepository.Save() when working with PublishingContent. You can simply assign the CustomId property, and the pipeline will take care of saving the changes for you.

#340519
Sep 24, 2025 13:50
* 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.