Content url caching not invalidating on synchronized sites



We've recently updated our CMS site from 11.13.1 to 11.20.0 and have noticed old urls being cached after a content item has been published. The server that did the content authoring has the old url cache broken but all synchronized sites don't have their url cache for the updated content updated.

This issue is reproducable on an Alloy tech site, when configured in a synchronized state.
For example with a css file that has its' url resolved by 'Url.ContentUrl()'.
Changing the 'Name in URL' value for the css file will cause it to not load on the synchronized sites as they are caching the old url.

What i've noticed is that the DefaultContentUrlCache is not using the ISynchronizedObjectInstanceCache, meaning that the url caching is only broken on the server the content authoring was done on, this matches up with what we've noticed on our live site aswell.

public DefaultContentUrlCache(IObjectInstanceCache cache, AncestorReferencesLoader ancestorLoader, RoutingOptions contentOptions)
            this._cache = cache;
            this._ancestorLoader = ancestorLoader;
            this._cacheExpirationTime = contentOptions.UrlCacheExpirationTime;
            if (this._cacheExpirationTime <= TimeSpan.Zero)
                throw new ArgumentException("The cache expiration time should be greater than zero");

I've tried replacing the DefaultContentUrlCache with an implementation of an IContentUrlCache that uses the ISynchronizedObjectInstanceCache and have not noticed any issues with the url caches on the synchronized sites.

I could see this being quite an issue for heavily authored synchronized sites.

Feb 25, 2021 5:33

Sounds like a good catch. Have you added it as a bug officially to support?

Feb 25, 2021 8:55

Hi Jakeb! Thanks for reporting this. I will investigate this and log a bug and get back here with a link to the bug so you can track it.

Feb 25, 2021 17:57

Thanks guys,

We've been in touch with Support who've raised a bug report

Mar 02, 2021 4:51
Mar 02, 2021 8:32

Thanks for the report, we've been encountering this issue as well and came to the same conclusion about the underlying cause.

We've done a workaround in the vein of what JakebJ suggested. We overwrite the registration for the IContentUrlCache with our implementation. The implementation we've used is just the original decompiled source code, just accepting an ISynchronizedObjectInstanceCache in the constructor rather than an IObjectInstanceCache .

public class ContainerConfig : IConfigurableModule
		public void ConfigureContainer(ServiceConfigurationContext context)
				context.ConfigurationComplete += ConfigurationComplete;

		private void ConfigurationComplete(object sender, ServiceConfigurationEventArgs e)
				// Override the default registration in EPiServer.Web.Routing.Internal.RoutingInitialization of
				// EPiServer.Web.Routing.Internal.IContentUrlCache with a registration for our implementation using
				// the ISynchronizedObjectInstanceCache rather than the default IObjectInstanceCache.
				// See for more details.
				// Remove once we are able to upgrade to EPiServer 11.20.6.
				var version = Assembly.Load("EPiServer.Cms.AspNet").GetName().Version;
				if (version < new Version(11, 20, 6))
                                                // Simpler than the default registration of IContentUrlCache - We always want to cache content URLs.
						e.Services.AddSingleton<IContentUrlCache, SynchronizedContentUrlCache>();

		public void Initialize(InitializationEngine context) { }

		public void Uninitialize(InitializationEngine context) { }
Edited, Mar 26, 2021 6:01
* 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.